上個月面試網易,面試官要我寫個二分查找,查找與target相等的數字的下標。。。我心想:簡單;刷刷一寫,面試官說:你這不對,int mid = (st + ed) >> 1;會溢出;
我:????
那好吧 我改成unsigned int tmp = st + ed ;int mid = tmp >> 1;
面試官: 你不用這麼複雜?
我:???
然後 面試官又提了一些需求,比如允許重複的數組中相等的最後一個數字的下標,允許重複的數組中相等的最前一個數字的下標,旋轉數組中的二分查找?允許重複的旋轉數組中實現二分查找?
印象中二分查找不是很容易的嗎?看來還是我太年輕了啊。。。
二分查找其實有好幾個坑。下面我來記錄一下
1.<=還是<?
其實都可以 只不過我個人習慣於使用<=
2.使用<=的時候會出現一個問題,那就是可能會出現死循環!
爲什麼呢?來看一下下面這個錯誤示例,問題爲已知一列可能有重複數字的有序數組,求某個元素出現時的第一個下標。
int findIndex(int target, int nums[], int n)
{
int st = 0;
int ed = n - 1;
while (st <= ed)
{
int mid = st + (ed-st)/2;
if (nums[mid] < target) st = mid + 1;
else if (nums[mid] > target) ed = mid - 1;
else ed = mid; //注意這一行
}
return st;
}
這個代碼實際上是有問題的,原因在於被我標記的那一行在st = ed = mid 且nums[mid] == target的時候,程序會死循環
所以應該改爲
int findIndex(int target, int nums[], int n)
{
int st = 0;
int ed = n - 1;
while (st <= ed)
{
int mid = st + (ed-st)/2;
if (nums[mid] < target) st = mid + 1;
else ed = mid - 1;
}
return st;
}
就滿足要求了