在電腦科學中,二分搜尋(英語:binary search),也稱折半搜尋(英語:half-interval search)[1]、對數搜尋(英語:logarithmic search)[2],是一種在有序陣列中查詢某一特定元素的搜尋演算法。搜尋過程從陣列的中間元素開始,如果中間元素正好是要查詢的元素,則搜尋過程結束;如果某一特定元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半中查詢,而且跟開始一樣從中間元素開始比較。如果在某一步驟陣列為空,則代表找不到。這種搜尋演算法每一次比較都使搜尋範圍縮小一半。二分演算法作為演算法考試和面試中的重點,因此對此做了一些總結。
關於二分演算法的一些基本操作
1.給定乙個有序(非降序)陣列a,求任意乙個i使得a[i]等於target,不存在則返回-1
2.給定乙個有序(非降序)陣列a,可含有重複元素,求最小的i使得a[i]等於target,不存在則返回-1 。//最樸素的二分查詢。基礎中的基礎
int search(int a, int n, int target)
return -1;
}
3.給定乙個有序(非降序)陣列a,可含有重複元素,求最大的i使得a[i]等於target,不存在則返回-1int searchfirstpos(int a, int n, int target)
/*
迴圈過程中,當low大於0時,a[low-1]是小於target的,因為a[mid] < target時,
low=mid+1;當high小於n-1時,a[high]是大於等於target的,因為a[mid] >= target時,
high = mid;迴圈結束時,low 等於 high,所以,如果a[low](a[high])等於target,
那麼low(high)就是target出現的最小位置,否則target在陣列中不存在。
*/
if(a[low] != target)
return -1;
else
return low;
}
4.給定乙個有序(非降序)陣列a,可含有重複元素,求最大的i使得a[i]小於target,不存在則返回-1。int searchlastpos(int a, int n, int target)
/*
迴圈過程中,當high小於n-1時,a[high+1]是大於target的,因為a[mid] > target時,
high=mid-1;當low大於0時,a[low]是小於等於target的,因為a[mid] <= target時,
low = mid;迴圈結束時,low 等於 high,所以,如果a[high](a[low])等於target,
那麼high(low)就是target出現的最大位置,否則target在陣列中不存在。
*/
if(a[high] != target)
return -1;
else
return high;
}
5.給定乙個有序(非降序)陣列a,可含有重複元素,求最小的i使得a[i]大於target,不存在則返回-1。int searchlastposlessthan(int a, int n, int target)
/*
迴圈過程中,當low大於0時,a[low]是小於target的,因為a[mid] < target時,
low=mid;當high小於n-1時,a[high+1]是大於等於target的,因為a[mid] >= target時,
high = mid-1;迴圈結束時,low 等於 high,所以,如果a[low](a[high])小於target,
那麼low(high)就是要找的位置,否則不存在這樣的位置(a[0] >= target時)。
*/
return a[low] < target ? low : -1;
}
有一些規律可以幫助記憶,不用臨時想很多。要求最小的xx,就用int searchfirstposgreaterthan(int a, int n, int target)
/*
迴圈過程中,當low大於0時,a[low-1]是小於等於target的,因為a[mid] <= target時,
low=mid+1;當high小於n-1時,a[high]是大於target的,因為a[mid] > target時,
high = mid;迴圈結束時,low 等於 high,所以,如果a[high](a[low])大於target,
那麼high(low)就是要找的位置,否則不存在這樣的位置(a[n-1] <= target時)。
*/
return a[high] > target ? high : -1;
}
low = mid + 1; high = mid;
要是求最大的xx,就用
low = mid + 1; high = mid - 1; 而且 mid = low + ((high - low + 1) >> 1)
做幾個題目拓展一下。
1.leetcode-74 搜尋二維矩陣
tips:這題其實是二分查詢的乙個小變形,平常的二分查詢是在一維陣列中進行的,而這次實在二維陣列中,可以把它看成乙個一維陣列。
2.leetcode-69 x的平方根bool searchmatrix(vector>& matrix, int target)
else if(matrix[mid/n][mid%n] > target)
else
} return false;
} }
tips:這題說白了就是上面的找最大小於某個數的那種方法。從1到x挨個去嘗試即可。
3.leetcode-50 pow(n,x)int mysqrt(int x) else
}}
tips:這題運用了類似二分查詢的方法,考察靈活運用。
4.leetcode-35 搜尋插入位置double mypow(double x, int n)
double res = mypow(x, n/2);
if(n % 2 == 0 && !isinf(res*res))
return res*res;
else if(n % 2 == 1 && !isinf(res*res*x))
return x*res*res;
else return 0.0;
}
tips:可以轉換為 找最小的大於等於target問題。
5.leetcode-33 搜尋旋轉排序陣列public:
int searchinsert(vector& nums, int target)
return low ;
}
tips:見注釋
leetcode-29 兩數相乘int search(vector& nums, int target)
int rot = low;
low = 0; high = nums.size()-1;
while(low <= high)
return -1;
}
tips:類似二分法的嘗試性演算法。
int divide(int dividend, int divisor)
*** -= temp;
res += multiple;
}return sign == 1 ? res : -res;
}
關於二分查詢
面試過很多人,對於初級程式設計師來說,我一般會給他簡單的已經比較成熟的演算法來考察他,一來來他對既有演算法的熟悉度,二來考察他對於一般程式設計問題的邏輯思維能力,二分查詢是有序數列中查詢的常用演算法,也是比較容易實現的查詢演算法之一,這個是stl的實現 template randomaccessit...
關於二分查詢
一 關於二分查詢 1.查詢目標值 當right nums.size 1時,判定條件應該為left right right賦值時也應該是mid 1 當right nums.size 時,判定條件應該為left 目標值的數 int search vector nums,int target return...
關於二分查詢
luogu 1571 眼紅的medusa 二分模版題 include using namespace std int n,m,x,l,r,mid,cnt,a 110000 b 110000 c 110000 intmain if x b l cnt c cnt x for int i 1 i cou...