Leecode第68题:x的平方根

mySqrt 解题思路(二分查找)

题目

求非负整数 x 的整数平方根 (向下取整),即最大的整数 r 满足 r * r <= x。不能使用内置 sqrt。

例如:

  • x = 4 → 2

  • x = 8 → 2(因为 2*2=4 <= 8,3*3=9 > 8)

  • x = 0 → 0


核心思想:在 [0, x] 里二分找「最大的可行值」

平方根 r 一定在 [0, x] 范围内(x >= 1 时 r <= x)。这个区间是单调的:

  • 若 mid * mid <= x,说明 mid 可行,答案至少是 mid ,往右找更大的

  • 若 mid * mid > x,说明 mid 太大,答案在左边

于是可以用二分查找,不断缩小区间,直到锁定答案。


关键:判断条件从「比较大小」变成「比较平方」

普通二分是找 nums[mid] == target,这题的「条件」是:

text

复制代码
mid * mid <= x   →  mid 是可行解,答案在 mid 或其右边
mid * mid > x    →  mid 太大,答案在 mid 左边

所以:

python

复制代码
if mid * mid <= x:
    left = mid + 1      # mid 可行,尝试更大的
else:
    right = mid - 1     # mid 太大,往左缩

为什么循环结束后返回 right

用 while left <= right,循环结束时一定是 left = right + 1 (left 刚越过 right)。此时:

  • right 是最后一个满足 mid*mid <= x 的位置 → 就是向下取整的平方根 ✅

  • left 是第一个 mid*mid > x 的位置 → 是平方根 + 1

所以返回 right。

一句话:right 停在「可行区的右边界」,left 停在「不可行区的左边界」,答案在 right。


代码

python 复制代码
class Solution:
    def mySqrt(self, x: int) -> int:
        left, right = 0, x
        while left <= right:
            mid = (left + right) // 2
            if mid * mid <= x:
                left = mid + 1      # mid 可行,往右找更大
            else:
                right = mid - 1     # mid 太大,往左缩
        return right                # 最大的可行值 = 平方根

执行流程演示

例 1:x = 8(答案 2)

text

复制代码
left=0, right=8
mid=4: 16>8   → right=3
mid=1: 1<=8   → left=2
mid=2: 4<=8   → left=3
mid=3: 9>8    → right=2
left=3 > right=2 → 结束,return right=2  ✅

例 2:x = 4(答案 2)

text

复制代码
left=0, right=4
mid=2: 4<=4   → left=3
mid=3: 9>4    → right=2
left=3 > right=2 → 结束,return right=2  ✅

例 3:x = 0(答案 0)

text

复制代码
left=0, right=0
mid=0: 0<=0   → left=1
left=1 > right=0 → 结束,return right=0  ✅

例 4:x = 1(答案 1)

text

复制代码
left=0, right=1
mid=0: 0<=1   → left=1
mid=1: 1<=1   → left=2
left=2 > right=1 → 结束,return right=1  ✅

边界与正确性

情况 处理
x = 0 right=0,返回 0 ✅
x = 1 返回 1 ✅
x 是完全平方数(4、9、16) 返回精确平方根 ✅
x 不是完全平方数(8) 返回向下取整 ✅
x 很大 mid*mid 在 Python 不会溢出(大整数),其他语言需防溢出

为什么 right = x 而不是 x - 1 :x=0 时 x-1=-1 会越界/跳过循环;x=1 时 x-1=0 也边界紧张。用 x 覆盖 [0, x] 最安全。


复杂度

  • 时间 :O(log x),每次区间减半

  • 空间 :O(1),只用几个变量


易错点

易错点 错误写法 正确
mid 公式 left + right // 2 (left + right) // 2
mid 位置 在循环外算一次 循环内每轮重算
循环条件 while left < right while left <= right
return 位置 写在循环里 循环外
返回值 return left return right
右边界 right = x - 1 right = x
比较 mid > x mid * mid > x

一句话记忆

在 [0, x] 里二分,mid*mid <= x 就往右找(left=mid+1),否则往左缩(right=mid-1);循环结束 left=right+1,返回 right 即向下取整平方根。 判断条件是「平方比较」,不是「大小比较」。

相关推荐
学长毕设8 分钟前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
梦里寻码29 分钟前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
SL_staff41 分钟前
离散制造排程破局:JVS-APS 四步闭环落地实践(开发者视角)
java·产品·全栈
这个昵称不容易1 小时前
SpringBoot 美容院管理系统:232个Java文件315个接口,5套角色从预约到发货一整条链路
java·springboot·毕设
猿人谷1 小时前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
装不满的克莱因瓶2 小时前
【SpringAI Alibaba】ReactAgent记忆管理MessageTrimmingHook与MessageDeletionHook
java·人工智能·ai·ai编程·springai·springaialibaba
文丑颜不良啊2 小时前
LeetCode2241~2260题目解析
java·leetcode
文丑颜不良啊2 小时前
LeetCode2321~2340题目解析
java·leetcode
驭渊的小故事2 小时前
Spring AOP 核心概念与通知类型详解
java·后端·spring