二分演算法的細節問題

2021-10-11 11:18:45 字數 2913 閱讀 8310

尋找乙個數

尋找左側邊界

尋找右側邊界

需不需要帶「=」號

需不需要+1

int

binarysearch

(int

nums,

int target)

return-1

;}

上面這段**中,可以發現while內的條件是<=而不是<,兩者有這樣的區別

符號區間返回條件

<=[left, right]left == right + 1

<[left, right)left == right

二分法,即把一段有序序列看作搜尋區間,通過檢視區間中的中間數來判斷預期結果在其左區間或右區間,並藉此使搜尋區間縮小一半的方法。

二分法總是會在搜尋區間內尋找我們的目標,可以發現,如果我們使用<號,而left == right時,將退出迴圈,顯然,這樣搜尋中就不會有最右邊的結果出現,即右開區間;如果我們使用<=號,則不會退出迴圈,即右閉區間

這段**使用的是left = mid + 1right = mid - 1,因為我們搜尋mid發現mid不是我們需要的數,就把mid剔除掉,再分出兩個區間:[left, mid-1][mid+1, right]

int

left_bound

(int

nums,

int target)

else

if(nums[mid]

< target)

else

if(nums[mid]

> target)

}return left;

}

首先需要注意while內的條件是<而不是 **<=**原因同上,即搜尋[left, right)

這段**使用的是left = mid + 1right = mid,和第乙個演算法不同,因為我們搜尋mid發現mid不是我們需要的數,我們就把mid剔除掉再分成兩個區間:[left, mid)[mid+1, right)

int

right_bound

(int

nums,

int target)

else

if(nums[mid]

< target)

else

if(nums[mid]

> target)

}return left -1;

// 注意

}

與搜尋左側邊界類似:

重點:num[mid] == target時,要使用left = mid - 1才能搜尋左側邊界。

最後返回left - 1,而不是left,因為

left = mid -1;

//看作 mid = left + 1;

如果序列中沒有target,我們在最後加上**:

//尋找乙個數:

while

(left < right)

return nums[left]

== target ? left :-1

;//尋找左側邊界

while

(left < right)

if(left == nums.length)

return-1

;return nums[left]

== target ? left :-1

;//尋找右側邊界

while

(left < right)

if(left ==0)

return-1

;return nums[left-1]

== target ?

(left-1)

:-1;

while裡面的條件決定了搜尋區間是開還是閉

由區間開閉決定mid加一還是不加

尋找乙個數:只需要尋找到其下標即可返回

尋找左側邊界,需要一直往左收縮直到最後找到左側邊界

尋找右側邊界,需要一直往右收縮直到最後找到右側邊界,最後返回left - 1

二分查詢細節問題

1.1 兩種實現 情況一 right nums.length int binary search int nums,int target else if nums mid target else if nums mid target 因為迴圈的結束條件是 left right,它們指向的元素未被判斷...

二分的細節

最普通的二分 搜尋區間 left right 每次搜尋mid後一分為二 left mid 1 和 mid 1 right 出while迴圈條件 left right 1 int binarysearch int nums,int target return 1 搜尋左側邊界的二分int left b...

演算法細節系列(5) 二分查詢應用

題目 於leetcode id title acceptance difficulty 35search insert position 39.3 easy 367valid perfect square 37.8 easy 153find minimum in rotated sorted arr...