【LeetCode 刷题笔记】69.x 的平方根 | 二分查找经典刷题题解

一、题目描述

给你一个非负整数 x ,计算并返回 x 的 算术平方根。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

示例 1:

复制代码
输入: x = 4
输出: 2

示例 2:

复制代码
输入: x = 8
输出: 2
解释: 8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

二、解题思路

  • 题目限制不能使用内置指数/开方函数,因此采用二分查找 实现,时间复杂度O(log n),符合高效要求。
  • 核心目标:找到不超过√x的最大整数;
  • 关键处理:用mid <= x/mid代替mid*mid <=x防止int溢出,同时单独处理x=0/x=1的边界情况避免除0异常;二分结束后返回right,即为所求的整数平方根。

三、代码实现(Java)

复制代码
class Solution {
    public int mySqrt(int x) {
        // 特殊情况处理:x=0和x=1时,算术平方根就是其本身,同时避免后续除法除0异常
        if(x == 0 || x == 1){
            return x;
        }
        // 调用自定义二分实现的sqrt函数,计算x的算术平方根整数部分
       return sqrt(x);
    }

    /**
     * 用二分查找计算x的算术平方根,返回不超过√x的最大整数
     * @param x 待计算平方根的非负整数(x≥2)
     * @return 不超过√x的最大整数
     */
    public int sqrt(int x){
        // 二分查找区间[1, x],初始左右边界
        int left = 1;
        int right = x;
        int mid = 0;
        while(left <= right){
            // 计算中间值,避免直接left+right相加导致int溢出
            mid = left + (right - left)/2;
            // 用mid <= x/mid代替mid*mid <=x,防止mid*mid超出int范围导致溢出
            if(mid <= x / mid){
                // mid的平方小于等于x,目标值在右半区间,更新左边界
                left = mid + 1;
            }else{
                // mid的平方大于x,目标值在左半区间,更新右边界
                right = mid - 1;
            }
        }
        // 循环结束时right即为不超过√x的最大整数
        return right;
    }
}

四、核心笔记 & 易错点解析

1. 整数溢出问题(关键处理)

直接用mid*mid <=x判断时,当mid较大,mid*mid可能超出int的最大值(2147483647),导致溢出变为负数,影响判断结果。

解决方案:用mid <= x/mid等价代替,避免乘法溢出;同时必须单独处理x=0x=1的情况,否则会出现除0异常。也可以将mid转为long类型后再做乘法判断,同样能避免溢出。

2. 二分循环结束的边界特性

由于循环条件为left <= right,当循环结束时,必然满足right < left,且right + 1 == left

此时right是最后一个满足mid <= x/mid的数,也就是不超过√x的最大整数,因此直接返回right即可。

3. 条件判断与返回值的对应关系

不管left == right与大于的情况放在一起还是与小于的情况放在一起,也就是无论条件写mid <= x/mid还是mid >= x/mid,最终都需要返回right,因为题目要求保留整数部分,取不超过√x的最大值:

  • 当条件为mid <= x/mid时,left会不断右移,循环结束时right是满足条件的最大值;
  • 当条件为mid >= x/mid时,right会不断左移,循环结束时right同样是不超过√x的最大值。

五、复杂度分析

  • 时间复杂度O(log n),二分查找每次将区间缩小一半,最多循环log₂(x)次,符合题目对高效算法的要求。
  • 空间复杂度O(1),仅使用常数级别的额外变量,无额外空间开销。

六、总结

本题核心是用二分查找实现无内置函数的开方运算,关键在于处理int溢出问题和理解二分循环结束的边界特性;掌握mid <= x/mid的溢出处理方式、循环结束时right的含义,以及条件判断与返回值的对应关系,就能轻松解决这类整数平方根问题。

相关推荐
灵智实验室1 小时前
PX4状态估计技术EKF2详解(一):EKF2 开篇——从分离到统一
算法·无人机·px 4
小智老师PMP1 小时前
六月PMP晚启动急救|现在开始,每天2-3小时,稳冲一次上岸(附可直接照搬计划)
算法·软件工程·求职招聘·产品经理·敏捷流程
tankeven2 小时前
动态规划专题(11):区间动态规划之三角剖分问题
c++·算法·动态规划
joshchen2152 小时前
强化学习基础(赵世钰)第一章
人工智能·深度学习·算法·机器学习·强化学习
小此方2 小时前
Re:从零开始的 C++ STL篇(十二)深度解析哈希函数设计、负载因子调节与两种冲突处理策略
c++·算法·哈希算法
lcj25112 小时前
【数据结构精讲】堆与二叉树从底层原理到代码落地:堆的构建 / 调整 / 排序 + 二叉树遍历 / 操作(附完整 C++ 源码 + LeetCode 题解)
数据结构·c++·leetcode
xuhaoyu_cpp_java2 小时前
单调栈(算法)
java·数据结构·经验分享·笔记·学习·算法
诙_3 小时前
C++数据结构--排序算法
数据结构·算法·排序算法
jieyucx3 小时前
Go 切片核心:子切片详解(下篇)
开发语言·算法·golang·切片