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 即向下取整平方根。 判断条件是「平方比较」,不是「大小比较」。

相关推荐
摇滚侠1 小时前
使用 VSCode 开发 Java 经验分享
java·经验分享·vscode
吹什么轩1 小时前
linux系统复习:进程优先级与O(1)调度
java·linux·算法
古法老登瞎折腾1 小时前
大数据智能运维实战(六):任务一直在等——排查调度队列与执行资源
java·大数据·运维·spring ai·mcp
开开心心就好1 小时前
安卓PDF处理工具,免费无广告零弹窗
android·服务器·开发语言·算法·pdf·ocr
Pniubi1 小时前
HashMap扩容全流程
java·开发语言·数据结构
考虑考虑10 小时前
JDK26中的Map.ofLazy
java·后端·java ee
鶴哥只手遮天13 小时前
Spring AI 2.0.1 深度解析-第 14 章 MCP 服务端(上):注解式实现与工具来源
java·人工智能·开源
鶴哥只手遮天13 小时前
Spring AI 2.0.1 深度解析-第 15 章 MCP 服务端(下):三种协议形态、Streamable 传输与状态管理
java·人工智能·开源
鶴哥只手遮天13 小时前
Spring AI 2.0.1 深度解析-第 16 章 向量存储(上):`VectorStore` 接口体系、`BatchingStrategy`
java·人工智能·开源