力扣“二分查找”类型题目相关笔记

本文精选了五道力扣上的二分查找经典题目进行解析,包括基础的二分查找、搜索插入位置、查找元素的第一个和最后一个位置等,并提供详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

代码随想录确实很好用,力扣刷题的顺序可以参考该网站。
很久没碰过算法题了,很多知识都忘了,就当复习了。

二、相关题目及相关知识点

1、704.二分查找

就是很简单的二分查找基础题,没什么好说的,就把二分查找的模板放这吧。

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

要注意mid值的计算方法,如果用mid = (right + left) / 2 的话有可能会产生溢出的情况。

2、35. 搜索插入位置

就是二分查找的微变形题目,因为题目中提到数组中无重复元素,所以比较简单,只需要找出target的位置然后输出就行,找不到target的位置直接输出left的值就可以。

tips:
二分查找中while的循环跳出条件是left>right的情况,所以最后right指向比target小的数,而left指向比target大的数,按照题目的插入要求,最后要输出left的值。

3、34. 在排序数组中查找元素的第一个和最后一个位置

题目提示数组为“非递减的”,所以这个数组里面有重复元素,难度相对地提升了一些。
其实思路也很简单,就是找target的left值以及target+1的left值。

class Solution {
public:
    int search(vector<int>& nums, int target){
        int left = 0, right = nums.size() - 1;
        while(left <= right){
            int mid = (right - left) / 2 + left;
            if(nums[mid] >= target){
                right = mid - 1; //这里的right就是帮助缩小范围的,帮助找到left
            }
            else left = mid + 1;
        }
        return left;
    }
    vector<int> searchRange(vector<int>& nums, int target) {
        int ansl = 0, ansr = nums.size() - 1;
        ansl = search(nums, target);
        if(ansl > ansr || nums[ansl] != target) 
            return vector<int>{-1, -1}; //这里就是利用ansr的初始值而已,没有其他含义
        ansr = search(nums, target + 1) - 1;

        return vector<int>{ansl, ansr};
    }
};

4、69. x 的平方根

就是从0到x范围用二分法,试mid * mid == x

class Solution {
public:
    int mySqrt(int x) {
        int left = 0, right = x;
        while(left <= right){
            long long mid = (right - left) / 2 + left;
            if(mid * mid == x) return mid;
            else if(mid * mid < x){
                left = mid + 1;
            }
            else
            {
                right = mid - 1;      
            }
        }
        if( x / left == left) return left;
        else  return left - 1;
    }
};

要注意的就是mid需要用long long定义。
最后判断的时候之所以是x / left == left,是因为这时的left一定不是0,所以才可以这样用。

如果不想用long long 定义mid,可以参照x / left == left将其改为x / mid == mid,不过要在while之前把mid等于0的情况先剔除掉。

5、367. 有效的完全平方数

上一道题的很简单的一个变形。

class Solution {
public:
    bool isPerfectSquare(int num) {
        int left = 0, right = num;
        while(left <= right){
            long long mid = (right - left) / 2 + left;
            if(mid * mid == num) return true;
            else if(mid * mid < num){
                left = mid + 1;
            }
            else
            {
                right = mid - 1;      
            }
        }
        if( num / left == left) return true;
        else  return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值