二分查找算法例题(一)

x的平方根

题目要求:

题目要求:给定一个整数x ,找到x的平方根(若x的算数平方根不为整数,则舍去小数部分,只保留整数部分作为x的平方根)

题目解析以及核心思路:

题目解析:

本题可以使用暴力解法完成即:从1开始枚举平方值,查找到第一个数i的平方>x时,i-1就是所求的平方根(若i的平方==x,则i为所求的平方根)


时间优化:

本题暴力解法的本质仍然是:"查找一个数",只不过是求其平方值来比较

因此对于查找算法,我们可以使用二分查找算法来解决这个问题。

解题准备:

二段性:

  • **i*i>x:**全是i*i大于x的,要缩小值,找到最接近x的平方
  • i*i<=x: 可能直接找到平方根,也可能找到i*i最接近x的最大数
    核心思路:

通过使用二分查找算法在1-x之间找到符合的平方根(1-x的范围一定能找到这个数)

  • mid*mid<=x:不确定是否是最接近x的平方根/直接就是平方根,因此更新left但不能越过mid

  • mid*mid>x:一定不是结果,因此要缩小范围去寻找最接近小于x的平方根/等于x的平方根


    细节补充:

  • 这里出现了mid*mid 可能会出现溢出现象 ,因此我们要使用long类型来处理

  • left不能越过mid更新,因此选取点要选取靠右的点,防止"死循环"

代码实例:

java 复制代码
class Solution {
    public int mySqrt(int x) {
    long left=1;
    long right=x;
    if(x==0){
        return 0;
    }
    while(left<right){
        long mid=left+(right-left+1)/2;
        if(mid*mid>x){
            //尽量去找最小贴近于x的平方根
            right=mid-1;
        }
        if(mid*mid<=x){
            left=mid;
        }
    }
    return (int)left;
    }
}

总结:

本题因为要寻找第一个比x大的平方,因此使用查找左端点的二分查找模板

要注意取值范围溢出的现象!!!

搜索插入位置

题目要求:

题目要求:给定一个目标值, 在有序递增数组中去寻找其位置下标。如果没有搜索到该目标值,则寻找目标值按照顺序,应当插入到的下标返回。

题目解析以及核心思路:

题目解析:

题目存在两种结果情况:

  • 能找到目标值==>直接返回下标
  • 找不到目标值==>寻找插入位置==>第一次出现比"目标值"大的位置/数组末尾

二段性:小于target/大于等于target(因为插入要找到第一个比目标值大的数)
核心思路:

目标:寻找到>=目标值的第一个数/在末尾插入

  • 第一种情况:因为x<目标值,因此要去右侧更大数的区间去寻找

  • 第二种情况:因为不确认当前数是否是第一个大于数,因此要去左侧更小数去寻找,但是不能越过当前的数


    细节补充:

  • 1. 如果整个数组中元素都比它小,则在数组末尾插入 ,要在循环结束后判断left是否等于数组长度-1

  • 2. 如果整个数组中元素都比它大,则在数组首位插入 ,就是简单的第二种情况,直接返回left即可

代码实例:

java 复制代码
class Solution {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<right){
            int mid=left+(right-left)/2;
            if(nums[mid]<target){
                left=mid+1;
            }
            else{
                right=mid;
            }
        }
        //在末尾添加的情况
        if(nums[left]<target){
            return left+1;
        }
        return left;
    }
}

总结:

本题因为是寻找第一个比目标数大于/等于的数,则使用寻找左端点的二分查找模板套用即可

要在末尾进行判断解决,末尾添加元素的下标问题

山脉数组峰顶索引

题目要求:

题目要求:给定一个形似山脉的数组(先上升,再下降),寻找并且返回这个"山脉数组"的最大值

题目解析以及核心思路:

题目解析:

**二段性:**山脉数组的特点:"一段上升,一段下降"

在上升段时,选定一个数,一定大于后一个数

在下降段时,选定一个数,一定小于后一个数
核心思路:

目标:找到山峰的索引(即数组最大值的下标)

  • 在上升段时,不确定当前数是否是最大的, 因此left不越过当前数,向右去寻找更大的
  • 在下降段时,当前数一定不是最大的,因此right向左侧去寻找更大的数

代码实例:

java 复制代码
class Solution {
    public int peakIndexInMountainArray(int[] arr) {
        int left=0;
        int right=arr.length-1;
        while(left<right){
            int mid=left+(right-left+1)/2;
            if(arr[mid]>arr[mid-1]){
                left=mid;
            }
            else{
                right=mid-1;
            }
        }
        return left;
    }
}

总结:

分析出本题独特的二段性:一段上升,一段下降。再套用模板即可。

相关推荐
小O的算法实验室4 小时前
IEEE TASE,基于MPC的多无人机协同搜索竞争群体优化方法
算法
Tbisnic5 小时前
BGE-M3 算法详解:从模型架构到三种检索方式的数学原理
算法·自然语言处理·大模型·bert·transformer·注意力机制
Brilliantwxx5 小时前
【算法从零到千】【55-58】哈希位图+常见数学运算 接口
算法
空堂与归6 小时前
用户分群找不到规律?用K-Means聚类算法自动发现数据模式
算法·机器学习·kmeans·聚类
动词ing7 小时前
【C语言】自定义函数+指针入门
c语言·开发语言·算法
重生之后端学习7 小时前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
一只小小的芙厨8 小时前
基础数论总结
笔记·学习·算法
夜不会漫长9 小时前
C++入门(1)
开发语言·c++·算法
wen_zhufeng10 小时前
IndexTTS 2.5 技术报告
人工智能·算法·机器学习
大熊背10 小时前
树莓派相机自动白平衡详解(四)
算法·树莓派·白平衡·isppipeline