-
最基本,精确查找
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right) {
int mid = (right + left) / 2;
if(nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return -1;
}
记忆方法:
查找区间[0,size-1],需要返回的是索引。
所以决定了终止循环之前,当left=right时,要查找[left,right]。
也决定了在mid基础上+1,-1,因为闭区间搜索。
返回值,找到mid,找不到-1。
2. 查找目标值区域的左边界/查找与目标值相等的第一个位置/查找第一个不小于目标值数的位置
def left_bound(self, nums, target):
if len(nums) == 0:
return -1
left, right = 0, len(nums) - 1
while left <= right: # 以(3,4),相等定为在3或4, 可知left都是正确位置
mid = (left + right) // 2
if nums[mid] == target:
right = mid - 1 # 偏激左移,可以理解为试图找到小于target的第一个位置
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
if left <= len(nums)-1 and nums[left] == target: return left # 注意left
else: return -1
记忆方法:
左边界问题: right偏激左移;
最终看left(right已经偏激);
最后还要看left是否符合条件:右移不能超过边界;需要等于target
另:如果是求最后一个小于目标值的数/查找比目标值小但是最接近目标值的数,
输出改为: 看right (跳出时right =left-1)
if right>-1:
return right
else:
return -1
3. 查找目标值区域的右边界/查找与目标值相等的最后一个位置/查找最后一个不大于目标值数的位置
def right_bound(self, nums, target):
if len(nums) == 0:
return -1
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
left = mid + 1 # 偏激右移,可以理解为试图找到大于target的第一个位置
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
if right >= 0 and nums[right] == target: return right # 注意right
else: return -1
记忆方法:
右边界问题: left偏激右移;
最终看right(left已经偏激);
最后还要看right是否符合条件:左移不能超过边界;需要等于target
另:如果是求第一个大于目标值的数/查找比目标值大但是最接近目标值的数,
输出改为: 看left(left = right+1)
if left < len(A):
return left
else:
return -1
4. 旋转数组的查找 leetcode33 二分查找的变种
https://leetcode-cn.com/problems/search-in-rotated-sorted-array/submissions/
比较mid和left的大小,两种情况。
每种情况的一边是确定有序的,另一边无序,但是都可以减治法搜索。