int binarysearch(int nums, int target) else if (nums[mid] < target) else if (nums[mid] > target)分析二分查詢的乙個技巧是:不要出現 else,而是把所有情況用 else if 寫清楚,這樣可以清楚地展現所有細節。本文都會使用 else if,旨在講清楚,讀者理解後可自行簡化。}return ...;
}
其中...標記的部分,就是可能出現細節問題的地方,當你見到乙個二分查詢的**時,首先注意這幾個地方。後文用例項分析這些地方能有什麼樣的變化。
另外宣告一下,計算 mid 時需要技巧防止溢位,建議寫成:mid = left + (right - left) / 2
,本文暫時忽略這個問題。
這個場景是最簡單的,可能也是大家最熟悉的,即搜尋乙個數,如果存在,返回其索引,否則返回 -1。
左閉右閉的模板
int binarysearch(int nums, int target)為什麼 while 迴圈的條件中是 <=,而不是 < ?return -1;
}
if(nums[mid] == target)return mid;
//...while(left < right)
return nums[left] == target ? left : -1; //注意 如果是插入位置 需要先判段left是否越界
為什麼 left = mid + 1,right = mid - 1?我看有的**是 right = mid 或者 left = mid,沒有這些加加減減,到底怎麼回事,怎麼判斷?
此演算法有什麼缺陷?
直接看**,其中的標記是需要注意的細節: //正常二分法左閉右開的模板
int left_bound(int nums, int target) else if (nums[mid] < target) else if (nums[mid] > target)為什麼 while(left < right) 而不是 <= ?}return left;
}
為什麼沒有返回 -1 的操作?如果 nums 中不存在 target 這個值,怎麼辦?
while (left < right)// target 比所有數都大
if (left == nums.length) return -1; //[1,2,2,4]搜尋8返回left 4,越界
// 類似之前演算法的處理方式
return nums[left] == target ? left : -1;
為什麼 left = mid + 1,right = mid ?和之前的演算法不一樣?
為什麼該演算法能夠搜尋左側邊界?
if (nums[mid] == target)right = mid;
為什麼返回 left 而不是 right?
尋找右側邊界和尋找左側邊界的**差不多,只有兩處不同,已標註:
int right_bound(int nums, int target) else if (nums[mid] < target) else if (nums[mid] > target)為什麼這個演算法能夠找到右側邊界?}return left - 1; // 注意
if (nums[mid] == target)if (left == 0) return -1; //這個例子搜尋0 就是返回left 0
return nums[left-1] == target ? (left-1) : -1;
先來梳理一下這些細節差異的因果邏輯:
第乙個,最基本的二分查詢演算法:
因為我們初始化 right = nums.length - 1所以決定了我們的「搜尋區間」是 [left, right]所以決定了 while (left <= right)同時也決定了 left = mid+1 和 right = mid-1因為我們只需找到乙個 target 的索引即可所以當 nums[mid] == target 時可以立即返回
第二個,尋找左側邊界的二分查詢:
因為我們初始化 right = nums.length所以決定了我們的「搜尋區間」是 [left, right)所以決定了 while (left < right)同時也決定了 left = mid+1 和 right = mid因為我們需找到 target 的最左側索引所以當 nums[mid] == target 時不要立即返回而要收緊右側邊界以鎖定左側邊界
第三個,尋找右側邊界的二分查詢:
因為我們初始化 right = nums.length所以決定了我們的「搜尋區間」是 [left, right)所以決定了 while (left < right)同時也決定了 left = mid+1 和 right = mid因為我們需找到 target 的最右側索引所以當 nums[mid] == target 時不要立即返回而要收緊左側邊界以鎖定右側邊界
又因為收緊左側邊界時必須 left = mid + 1所以最後無論返回 left 還是 right,必須減一
**自詳解二分查詢演算法 - murphy_gb - (cnblogs.com)
二分法細節總結
二分法的思想很容易理解,但是細節處理卻是乙個難點。很容易就容易出錯。這裡總結一下這些細節。區間為 left,right 情況 右邊指標取不到元素 初始化 left 0 right arr.length 迴圈條件 left right 注意事項 left 的更新是取到值的情況 right的更新是不取到...
C 二分法查詢,遞迴二分法
用二分法來求需要查詢的值.includeusing namespace std 查詢key元素是否存在 int findkey const int buf 100 const int ilen,const int key else right left mid 1 查詢失敗 return 1 查詢k...
python二分法查詢 Python 二分法查詢
二分法查詢主要的作用就是查詢元素 lst 1,3,5,7,12,36,68,79 資料集 百萬級資料 num int input 請輸入你要查詢的元素資訊 for el in lst if num el print 存在 break else print 不存在 len lst 0 1 2 3 4 ...