二分模板有兩個,分別適用於不同的情況。
演算法思路:假設目標值在閉區間[l, r]
中,每次將區間長度縮小一半,當l = r
時,我們就找到了目標值。
版本一
當我們將區間[l, r]
劃分成[l, mid]
和[mid + 1, r]
時,其更新操作時l = mid + 1
或者[r = mid]
,計算mid
時不需要加1。
版本二
當我們將區間[l, r]
劃分成[l, mid - 1]
和[mid, r]
時,其更新操作是r = mid - 1
或者l = mid
,此時為了防止死迴圈,計算mid
時需要加1。
70%的二分題目都是具有單調性。
95%的二分題目都是具有兩段性,前一段滿足該性質,後一段則不滿足該性質。
如果要二分前一段的右邊界,那麼使用模板ii,如果要二分後一段的左邊界,那麼使用模板i。
實現 int sqrt(int x) 函式。
計算並返回 x 的平方根,其中 x 是非負整數。
由於返回型別是整數,結果只保留整數的部分,小數部分將被捨去。
輸入: 4
輸出: 2
輸入: 8
輸出: 2
說明: 8 的平方根是 2.82842...,
由於返回型別是整數,小數部分將被捨去。
class
solution
return lo;
}}
分析:
當mi * mi <= x時,說明答案在[mi,hi]之間,所以 lo = mi;
當mi * mi > x時,說明答案在[lo, mi - 1]之間,所以 hi = mi - 1。
推出 mi = (lo + hi + 1) >> 1。
給定乙個排序陣列和乙個目標值,在陣列中找到目標值,並返回其索引。如果目標值不存在於陣列中,返回它將會被按順序插入的位置。
你可以假設陣列中無重複元素。
輸入: [1,3,5,6], 5
輸出: 2
輸入: [1,3,5,6], 7
輸出: 4
class
solution
return lo;
}}
在排序陣列中尋找大於等於target的最小元素,那麼需要先排除陣列中最大的元素都小於target的情況,然後使用二分法。
對於此題,尋找的是右段的最左邊界元素,所以採用模板i。
給定乙個按照公升序排列的整數陣列 nums,和乙個目標值 target。找出給定目標值在陣列中的開始位置和結束位置。
你的演算法時間複雜度必須是 o(log n) 級別。
如果陣列中不存在目標值,返回 [-1, -1]。
輸入: nums = [5,7,7,8,8,10], target = 8
輸出: [3,4]
輸入: nums = [5,7,7,8,8,10], target = 6
輸出: [-1,-1]
class
solution;if
(nums.length ==0)
return res;
//找出排序陣列中target出現的第乙個位置 >= target的最左元素索引
int n = nums.length -1;
int lo =
0, hi = n;
while
(lo < hi)
if(nums[lo]
!= target)
else
lo =0;
hi = n;
while
(lo < hi)
res[1]
= lo;
return res;
}}
此題需要用到兩個模板。
首先找出起始位置,如果起始位置的元素不等於target,那麼直接返回res;
如果等於target,那麼開始找結束位置返回即可。
編寫乙個高效的演算法來判斷 m x n 矩陣中,是否存在乙個目標值。該矩陣具有如下特性:
輸入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]target = 3
輸出: true
輸入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]target = 13
輸出: false
class
solution
int row = lo;
hi = matrix[row]
.length -1;
lo =0;
while
(lo < hi)
return matrix[row]
[lo]
== target;
}}
這道題從一維的有序陣列轉換為二維的有序陣列,但是本質沒有變。
第一,先找到target所在的行,為了方便起見,將matrix[row][0]的元素模擬為乙個一維有序陣列,尋找小於等於target的最右元素;
第二,在row裡,尋找大於等於target的最左元素即可,返回 == target。
假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。
( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
請找出其中最小的元素。
你可以假設陣列中不存在重複元素。
輸入: [3,4,5,1,2]
輸出: 1
class
solution
return nums[lo];}
}
1024 二分查詢(上)
目錄 一 什麼是二分查詢?二 時間複雜度分析?三 如何實現二分查詢?四 使用條件 應用場景的侷限性 五 思考 二分查詢針對的是乙個有序的資料集合,每次通過跟區間中間的元素對比,將待查詢的區間縮小為之前的一半,直到找到要查詢的元素,或者區間縮小為0。1.時間複雜度 假設資料大小是n,每次查詢後資料都會...
演算法筆記 二分查詢(上)
5.總結 二分查詢針對的是乙個有序的資料集合,查詢思想有點類似分治思想。每次都通過跟區間的中間元素對比,將待查詢的區間縮小為之前的一半,直到找到要查詢的元素,或者區間被縮小為 0。二分查詢是目前為止遇到的第乙個時間複雜度為 o logn 的演算法。堆 二叉樹的操作等等,它們的時間複雜度也是 o lo...
二分查詢 2
v1中使用while迴圈的方式,我們也可以不使用迴圈,使用遞迴的方式來實現 public static intbinarysearch v2 int array,int value public static intmysearch int array,int start,int end,int v...