二分查找算法例题(一)

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;
    }
}

总结:

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

相关推荐
退休倒计时1 小时前
【每日一题】LeetCode 17. 电话号码的字母组合 TypeScript
算法·leetcode·typescript
粘稠的浆糊1 小时前
[AtCoder - abc465_d ]X to Y题解
数据结构·c++·算法
鱼儿也有烦恼1 小时前
数据结构合集
算法·algorithm
兰令水2 小时前
hot100【acm版】【2026.7.11/12打卡-java版本】
java·开发语言·数据结构·算法·职场和发展
研來如此2 小时前
图像文件大小
人工智能·算法·计算机视觉
千纸鹤安安2 小时前
开源 Agent 框架实战:用自然语言替代 Crontab 做运维
算法
从零开始的代码生活_2 小时前
C++ string 详解:常用接口、字符串算法与深拷贝实现
开发语言·c++·后端·学习·算法
Keven_112 小时前
算法札记:差分约束系统为啥叫差分约束系统Σ(っ °Д °;)っ
算法·差分约束系统
临沂堇2 小时前
刷题日志 | LeetCode Hot 100 双指针
算法·leetcode·职场和发展