第 1 部分 - 快速回答这个特定问题
这不是对二分搜索的完整总结,但我会简短地解决这个问题。
这两个 while 循环条件的主要区别,给定
1. low(left) 和 high(right) 指针相应更新。 “相应地”,请参阅第 3 部分。
2.假设LOW(LEFT)和HIGH(RIGHT)的边界没有重复
3. 假设目标存在于数组
while(low <= high) 在[LOW,HIGH]的范围内进行搜索,包括两端。
相比之下,while(low < high) 在 [LOW, HIGH) 范围内进行二分搜索,右/高端独占。对于上/右范围/部分中的目标的二进制搜索,他们总是错过最后/右/高的检查,最后一个low(left) 停止。为了使范围完全覆盖,通常建议根据最后一个low(left) 指针进行另一个判断。
第 2 部分 - 一般准则
可能是任意的一般准则:
1. 处理数组中肯定存在目标,且搜索的数组不包含重复的情况时,首选while(low <= high)
2.在处理数组中不一定存在target,且数组可能包含重复的情况时,推荐while(low < high)。
第 3 部分 - 代码
low(left) 和 high(right) 指针“相应”更新
public int binarySearch(int[] nums, int target){
int left = 0, right = nums.length - 1;
// please pay attention to the initial condition of right(ptr)
while(left <= right){
// to floor the mid
int mid = left + (right - left) / 2;
// to check whether the middle element is equal to the target in every iteration
if(nums[mid] == target) return mid;
else if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public int binarySearch(int[] nums, int target){
// please pay attention to the initial condition or the right(ptr)
int left = 0, right = nums.length;
while(left < right){
int mid = left + (right - left) / 2;
// please pay twice attention to the equality case
if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
第 4 部分 - 变体,更高级
警告:可能会引起混淆
对于while(low <= high)的类型:
public int binarySearchWithFlooringMid(int[] nums, int target){
// please pay attention to the initial condition of right(ptr)
int left = 0, right = nums.length - 1;
while(left <= right){
// to floor the mid
int mid = left + (right - left) / 2;
// to check whether the middle element is equal to the target in every iteration
if(nums[mid] == target) return mid;
else if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return -1;
}
public int binarySearchWithCeilingMid(int[] nums, int target){
int left = 0, right = nums.length - 1;
while(left <= right){
// to ceil the mid
int mid = left + (right - left + 1) / 2;
// to check whether the middle element is equal to the target in every iteration
if(nums[mid] == target) return mid;
else if(target > nums[mid]) {
left = mid;
} else {
right = mid - 1;
}
}
return -1;
}
对于while(low < high)的类型
public int binarySearchLeftmost(int[] nums, int target){
int left = 0, right = nums.length;
while(left < right){
int mid = left + (right - left) / 2;
// please pay twice attention to the equality case
if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
public int binarySearchRightmost(int[] nums, int target){
int left = 0, right = nums.length;
while(left < right){
int mid = left + (right - left) / 2;
// please pay twice attention to the equality case
if(target < nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return right - 1;
}
这篇文章并未涵盖二进制搜索方面的所有情况。还有更复杂的需求,等我掌握了再细讲。