(算法)二分查找

93 阅读1分钟

题目链接

力扣

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

拿到一个二分问题

  1. 选择一种写法,左闭右闭,左闭右开,一般就是这两种
  2. 根据上面的写法写出对应即可

左闭右闭写法 理解:

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;

}

};