2 二分查詢(上)

2021-10-23 16:46:52 字數 3287 閱讀 9780

二分模板有兩個,分別適用於不同的情況。

演算法思路:假設目標值在閉區間[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...