注:数组是有序的,和面试官确认过。方法签名是 int bbsearch(int[] sorted,int ta);也和面试官确认过。 前天面试某司,让写个二分查找,输入一个数组和目标值 ta,输出小于 ta 的最大值的下标(更新),没有则输出 -1。这样的题目我做过很多了,很快就写出了如下版本(java)。然后发生了如下对话(回忆): 面:你这个代码没问题吗? 我:这里 r 表示不可达的右边界,可以简化判断。根据我做题的经验,感觉没有问题。 面:如果 p=2,r=3,a[m]<ta,你算法就有死循环了。 我:这个应该不会,这样的条件应该不会发生。我再看看。 。。。。(肉眼 debug,此时面试官在看电脑). 大概三分钟后,我仍然没看出自己代码有什么问题。为了降低 bug,我把 p=m 修改成了 p=m-1。 我:我修改了一下,这样应该不会死循环了。 面:...(略作思考) 我:这里要加个条件,防止 p<0。 面:这题就到这里吧。
/** solution in java*/
public static int bbsearch(int[] a,int ta){
int p=0;
int r=a.length;
while(p<r){
int m=p+(r-p)/2;
if(a[m]<ta){
if(m+1==a.length ||a[m+1]>=ta)return m;
p=m; // 被修改的一行
}else{
r=m;
}
}
return -1;
}
后来得知自己挂掉了,感觉很郁闷,这样的代码都能写错?于是刚刚拿 ruby 改写了一遍。测试都通过了。 面试官提到的死循环,我感觉是不可能发生的。如果能达到他说的条件,那的确有可能死循环。但实际上无法满足那个条件,个人感觉。 无论有是面试措辞,还是程序,或者(能不能)达到死循环的用例,都希望能得到大家的提示。求职心切,先谢了。
# my ruby solution
def bbsearch(a,ta)
return -1 if not a
p,r=0,a.length
while p<r
m=(p+r)/2
return m if a[m]<ta&&(m+1>=r || a[m+1]>=ta)
a[m]<ta ? (p=m):(r=m)
end
-1
end
a=[1,2,3,7,9]
p bbsearch(a,3)
a=[1,1,2,2]
p bbsearch(a,3)
p bbsearch([2,2,2,2],3)
p bbsearch([2,2,2],3)
p bbsearch([0,1,2],3)