二分搜尋總結

2021-10-24 09:37:21 字數 2844 閱讀 4399

看了這篇帖子,對思路很簡單,細節是魔鬼感同身受,故自己來做個總結。

在乙個一維有序陣列 nums 中查詢 target 是否存在,存在返回 index ,不存在返回 -1:

public int binarysearch(int nums, int target)  else if (nums[mid] < target)

left = mid + 1;

else

right = mid - 1;

}return -1;

}

需要注意的是 right 的賦值及 while 條件:我們設定 right = len - 1 時,二分搜尋的區間為[left,right],搜尋迴圈終止的條件為:①找到 target ,即 nums[mid] == target ,則返回 mid;②當 left > right 時表明未找到 target,終止迴圈,返回-1。那麼為什麼迴圈條件是 left <= right:left < right 顯然是必須的,我們再考慮臨界情況,當left + 1 = right時進入迴圈,這時求得 mid = left,若 nums[mid] == target,程式直接返回 mid;若 nums[mid] < target,則需要右移 left,left = mid + 1 = left + 1 = right,此時 left = right ,搜尋空間 [left,left](或 [right,right]) 並不為空,若迴圈條件中沒有等於,則遺漏了該處元素的比較(當然也可以在迴圈外補充上此處比較);若 nums[mid] > target,則需要左移 right,right = mid - 1 = left - 1,此時 left > right,搜尋空間 [left,right]為空,迴圈結束。

先來說明一下左邊界和右邊界,比如 nums = ,那麼當 target = 2 時,求左邊界的返回值為 1(最左邊的2),右邊界的返回值為 4(最右邊的2)。對於這種情況,基本的二分搜尋返回的是其中的乙個 2 而不是最左(右)邊的。

先來看搜尋左邊界:

public static int binarysearchleft(int nums, int target)  else if (nums[mid] < target)

left = mid + 1;

else

right = mid;

}return left;

}

該種情況下我們的搜尋區間為[left,right),所以賦值 right = len 且迴圈條件為 left < right,當 left = right 時跳出迴圈[left,left)為空不會錯過解。同樣考慮當 left + 1 = right 時,mid = left,若 nums[mid] >= target,right = mid = left 迴圈結束;若nums[mid] < target,left = left + 1 = right 迴圈結束。可以看到最終迴圈結束,left 和 right 都指向陣列中第乙個大於等於 target 的元素。

右邊界和左邊界類似,當 nums[mid] == target 時,不要立即返回,而是增大「搜尋區間」的下界 left,使得區間不斷向右收縮,達到鎖定右側邊界的目的:

public static int binarysearchleft(int nums, int target) 

return left - 1;

}

同樣分析 left + 1 = right 時,mid = left,若 nums[mid] >= target,left = mid + 1 = left + 1 = right 迴圈結束;若nums[mid] < target,right = mid 迴圈結束。可以看到最終迴圈結束,left-1 和 right-1 都指向陣列中最後乙個小於等於 target 的元素。

與求邊界的二分查詢,最大的區別時搜尋空間不同,所以定義左右標記也不同。

基本二分查詢

left = 0;

right = len - 1;

迴圈條件:left <= right

if (nums[mid] == target) 

return mid;

else if (nums[mid] < target)

left = mid + 1;

else

right = mid - 1;

左邊界

left = 0;

right = len;

迴圈條件:left < right

if (nums[mid] == target) 

right = mid;

else if (nums[mid] < target)

left = mid + 1;

else

right = mid;

右邊界

left = 0;

right = len;

迴圈條件:left < right

if (nums[mid] == target)

left = mid + 1;

else if (nums[mid] < target)

left = mid + 1;

else

right = mid;

題目1:尋找 nums 中第乙個 >= target 的數或者小於 target 的數有幾個等情況。

幾種二分搜尋總結

1.如果有重複,找的是最左邊 leftmost 的那個的index。如果不存在,返回的是應該插入的index,這裡陣列長度是可變的。見乙個easy題 35題 class solution else return lo 2.如果存在,返回index 如果有重複的,因為它找到重複中的任何乙個就retur...

二分搜尋的總結 續

前面已經有介紹二分搜尋的了,這裡再次貼出乙個 這是 程式設計珠璣 第九章,對二分搜尋的最後的優化。還和前面一樣,分成三個子程式,第乙個函式binarysearch是典型的二分搜尋,只不過把三次比較換成了兩次,第二個函式binarysearchge是返回搜尋值target的最左邊的乙個,如果不存在,就...

專題總結 二分搜尋專題

1.1從有序陣列中查詢某值 陣列長 目標值 int n,k int arr n void solve return lst 此時 fst 1 lst stl關於二分的應用 stl lower bound begin,end,key 從陣列的begin位置到end 1位置二分查詢第乙個大於或等於num...