题目链接
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
拿到一个二分问题
- 选择一种写法,左闭右闭,左闭右开,一般就是这两种
- 根据上面的写法写出对应即可
左闭右闭写法 理解:
1⃣️ 既然是左闭右闭,那么left == right的时候是有意义的,所以left <= right
2⃣️ if(target > nums[mid]) 就是说目标数在右边,我们就要对left进行更新,因为我们的左边是闭的,然而我们现在的nums[mid]不是我们要的数,我们故这样更新left = mid + 1; 反之,如果左边是开的话,nums[mid]不是我们要的数,右边是我们要的数,我们就left = mid
3⃣️ if(target < nums[mid]) 就是说目标数在左边,我们就要对right进行更新,因为我们的右边是闭的,然而我们现在的nums[mid]不是我们要的数,我们故这样更新right = mid - 1; 反之,如果右边是开的话,nums[mid]不是我们要的数,左边是我们要的数,我们就right = mid
class Solution {
public:
int search(vector<int>& nums, int target) {
//[left,middle]写法
int left = 0, right = nums.size()-1; // 下标
while(left <= right){
int middle = left + ((right-left)>>1);
if(target < nums[middle]){
right = middle - 1;
}
else if(target > nums[middle]){
left = middle + 1;
}
else return middle;
}
return -1;
}
};
左闭右开写法
和上面思想相似,这里提出易错点:
1⃣️ right刚开始是size而不是size-1 ,原因是右边是开的,第一步也要做到这个条件
2⃣️ 因为右边是开的,所以target在左边的时候,右边更新的时候是right = mid
class Solution {
public:
int search(vector<int>& nums, int target) {
//[left,right)
int left = 0, right = nums.size();//这边要注意right不是size-1
while(left < right)
{
int mid = left + (right - left)/2;
if(nums[mid] > target){
right = mid;
}
else if(nums[mid] < target){
left = mid + 1;
}
else return mid;
}
return -1;
}
};