题目描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ij5mOf5t-1631589145189)(C:\Users\落雨\AppData\Roaming\Typora\typora-user-images\image-20210830185956018.png)]
解题思路
代码实现
#include <iostream>
#include <vector>
#include "704二分查找.h"
using namespace std;
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;//防止溢出
if (nums[mid] < target)
{
left++;
}
else if (nums[mid] > target) {
right--;
}
else
{
return mid;
}
}
return -1;
}
int main()
{
int a[7] = { 1, 2, 3, 4, 5, 6, 7 };
vector<int> nums(a, a+7);
int target = 8;
int i=search(nums, target);
cout << i << endl;
}
实现代码的思路
使用二分查找的条件
二分查找使用的条件是按排好的顺序数组进行查找
while循环判断的条件
正序就是左边小于等于右边,当大于右边时跳出循环,输出未找到时的规定数据
里面判断条件
数据中间的数跟目标数据进行比较,当中间数据大于目标值,left向左移动
当中间数据小于目标值,right向右移动
剩下一种等于目标值然后进行返回
获得的收获
算两数之间的中间数值时要可以使用左边数据+(右边数据-左边数据)/2
这样数据就有更小的可能性进行溢出
对于寻找左右边界的二分搜索,常见的手法是使用左闭右开的「搜索区间」,我们还根据逻辑将「搜索区间」全都统一成了两端都闭,便于记忆,只要修改两处即可变化出三种写法:
int binary_search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if(nums[mid] == target) {
// 直接返回
return mid;
}
}
// 直接返回
return -1;
}
int left_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定左侧边界
right = mid - 1;
}
}
// 最后要检查 left 越界的情况
if (left >= nums.length || nums[left] != target)
return -1;
return left;
}
int right_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定右侧边界
left = mid + 1;
}
}
// 最后要检查 right 越界的情况
if (right < 0 || nums[right] != target)
return -1;
return right;
}