leetcode刷题笔记——704、278、35二分查找

二分查找

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二分查找模板

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int low=0;
        int high = nums.size()-1;
        while(low<=high){
            int mid = low +(high - low)/2;
            if(nums[mid] == target){
                return mid;
            }
            else if(nums[mid]<target){
                low = mid + 1; 
            }
            else{
                high = mid -1;
            }
        }
        return -1;
    }
};

这个是二分查找的模板,有关二分查找的题都在这个模板上删减而来。

第一题解思路

第一题就是简单的二分查找,直接用模板

第二题解思路

第一个错误的版本,即要找到有重复数组中对应值的最左边界,实际上还是二分查找问题。只需要在模板中注意,数组起始为1结束为n(而非其实为0结束为n-1)。

while中取low<high,不取等号。此时跳出while循环的条件就是low == high。可以对取不取等号做简单理解,取low<=high时,跳出循环时high在左边而low在右边,(比如3 5,查找4,最后一定是high指向3,low指向5,方便后续操作);取low<high时,跳出循环时high=low,假设二分查找未找到,high=low的情况low和high可能指向前一个位置也可能指向后一个位置(比如3 5,查找4,low和high可能同时指向3,也可能同时指向5),不好确定位置。

在nums[mid]找到 target时,将右边界置为此mid(不需要-1,因为此时nums[mid]为T,是潜在的解,不能因为判断过就跳过)。

// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
public:
    int firstBadVersion(int n) {
        int low = 1;
        int high = n;
        while(low<high){
            int mid = low+(high-low)/2;
            if(isBadVersion(mid)){
                high = mid;
            }else{
                low = mid + 1;
            }
        }
        return low;
    }
};

第三题解思路

二分插入问题,取模板,low=0,high = n-1,毋庸置疑

while中应该取low<=high,因为这样,二分查找没找到时,low指向该空位的下一个,而high指向该空位的上一个,找位置插入一定是插在该空位的下一个位置,(比如3 5 ,插入4,二分查找取等号,未找到时low一定指向5而high一定指向3,我们应该在3 5之间插入4即在空位之后(5的位置)插入),也就是说是插在low指向的位置。

每次更新low后保存,如果未找到(表现为跳出while循环)即在low的位置插入即可。
注意初始res设置为0,是因为nums中最小数都比target大的时候,在第0位置插入。

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int low = 0;
        int high = nums.size()-1;
        int res = 0;
        while(low<=high){
            int mid = low + (high - low)/2;
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] < target){
                low = mid + 1;
                res = low;
            }else{
                high = mid - 1;
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值