给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
示例 1:
输入:nums
= [-1,0,3,5,9,12],target
= 9 输出: 4 解释: 9 出现在nums
中并且下标为 4
示例 2:
输入:nums
= [-1,0,3,5,9,12],target
= 2 输出: -1 解释: 2 不存在nums
中因此返回 -1
首先考虑到的是比较一般的二分查找算法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int len=nums.size();
int start=0;
int end=len-1;
while(end>start)
{
int temp = (end + start)/2;
if(nums[temp]==target)
return temp;
else if(nums[temp] > target)
{
end = temp - 1;
}
else
start = temp + 1;
}
return -1;
}
};
然后在单一用例上发生报错:
输入: [5] 5
输出: -1
预期结果:0
原因是在while循环条件是应该写出大于等于号
将while(end>start)改为while(end>=start)后,代码可ac
之前自己没有弄懂,下面给出解释(参考labuladong大佬在本题的题解)
链接:https://leetcode-cn.com/problems/binary-search/solution/er-fen-cha-zhao-xiang-jie-by-labuladong/
为什么在本题二分查找中 while 循环的条件中是 <=,而不是 <
在本题中算法本质是使用的左闭右闭的区间,即[a,b],若使用while(end>start)的条件进行判别的话,此时的循环结束条件可能是end==start,在本算法中不适用,因为例如[2,2]中的2我们是没有讨论过的,会遗漏可能情况。
note:
计算 mid 时需要防止溢出,代码中 left + (right - left) / 2 就和 (left + right) / 2 的结果相同,但是有效防止了 left 和 right 太大直接相加导致溢出