学习博客:https://blog.csdn.net/qq_45978890/article/details/116094046
二分查找需要的条件
- 用于查找的内容逻辑上来说是需要有序的
- 查找的数量只能是一个,而不是多个
区间问题
- 左闭右闭[left, right]
- 左闭右开[left, right)
奇偶问题、边界问题
- 两边数量不一样是一定会出现的情况,但是这种情况并不影响我们对中间数字和目标数字大小关系的判断。数组长度是偶数还是奇数不影响怎么排除的问题,无非是多排除一个数字或者少排除一个数字。
- 真正影响的是中间那个数字到底该不该加入下一次的查找中,也就是边界问题。
- 影响循环条件:while循环中left、right是否取等。
- 影响边界是否取等。
左闭右闭
- 循环条件要使用while(left <= right),因为当(left == right)这种情况发生的时候,得到的结果是有意义的。
- if(nums[middle] > target) , right 要赋值为 middle - 1, 因为当前的 nums[middle] 一定不是 target ,需要把这个 middle 位置上面的数字丢弃,那么接下来需要查找范围就是[left, middle - 1]。
int search(int nums[], int size, int target) //nums是数组,size是数组的大小,target是需要查找的值
{
int left = 0;
int right = size - 1; // 定义了target在左闭右闭的区间内,[left, right]
while (left <= right) { //当left == right时,区间[left, right]仍然有效
int middle = left + ((right - left) / 2);//等同于 (left + right) / 2,防止溢出
if (nums[middle] > target) {
right = middle - 1; //target在左区间,所以[left, middle - 1]
} else if (nums[middle] < target) {
left = middle + 1; //target在右区间,所以[middle + 1, right]
} else { //既不在左边,也不在右边,那就是找到答案了
return middle;
}
}
//没有找到目标值
return -1;
}
左闭右开
- 循环条件使用while (left < right)
- if (nums[middle] > target), right = middle,因为当前的 nums[middle] 是大于 target 的,不符合条件,不能取到 middle,并且区间的定义是 [left, right),刚好区间上的定义就取不到 right, 所以 right 赋值为 middle。
int search(int nums[], int size, int target)
{
int left = 0;
int right = size; //定义target在左闭右开的区间里,即[left, right)
while (left < right) { //因为left = right的时候,在[left, right)区间上无意义
int middle = left + ((right - left) / 2);
if (nums[middle] > target) {
right = middle; //target 在左区间,在[left, middle)中
} else if (nums[middle] < target) {
left = middle + 1;
} else {
return middle;
}
}
// 没找到就返回-1
return -1;
}