Leetcode 704. 二分查找 两种方法详解
题目
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
思路
二分法的区间定义一般有两种,一种是左闭右闭[left,right],另一种是左闭右开[left,right),
-
写法一
- 因为left与right相等的情况在[left,right]区间是有意义的,所以在while(left <= right)中要使用<=
- 如果在nums[middle] 大于 target,则更新搜索范围,将右下标right更新为middle - 1。因为当前这个nums[middle]一定不是target,所以接下来要查找的左区间结束下标位置是middlle - 1
-
写法二
- target在一个左闭右开区间,while(left < right)
- 如果nums[middle] 大于target,right = middle,nums[middle] < target, left = middle + 1
代码
- 写法一的代码
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
// 定义target在左闭右闭区间
while(left <= right)
{
// 防止溢出
int middle = left + ((right - left) / 2);
if(nums[middle] > target)
{
right = middle - 1;
}
else if (nums[middle] < target)
{
left = middle + 1;
}
else
{
return middle;
}
}
return -1;
}
};
- 写法二的代码
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();// 定义左闭右开区间
while(left < right)
{
int middle = left + ((right - left) >> 1);
if(nums[middle] > target)
{
right = middle;// target在左区间[left,middle]
}
else if(nums[middle] < target)
{
left = middle + 1;// target在右区间[middle + 1,right]
}
else
{
return middle;
}
}
return -1;
}
};