图解题库 / 二分

69. x 的平方根

简单 含交互动画

学完这道你应该能: 说清它为什么用「二分」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

题目描述

求 x 的算术平方根,只保留整数部分(向下取整)。

x = 8
输出 = 2 (2²=4≤8,3²=9>8)

思路解析

k 越大 k² 越大,单调的。在 [0, x] 里二分 k:k² ≤ x 说明还能更大(记录答案,l 右移);k² > x 说明太大(r 左移)。

区间 [0,8] · mid=4:候选答案排成 0~8,mid=4:4²=16 > 8,太大,r 收到 3。

mid=1:区间 [0,3],mid=1:1²=1 ≤ 8,可行!记下 ans=1,试更大的,l=2。

mid=2:区间 [2,3],mid=2:2²=4 ≤ 8,更新 ans=2,继续试更大,l=3。

mid=3:区间 [3,3],mid=3:3²=9 > 8,太大,r=2。此时 l>r,循环结束。

答案 = ans = 2:最后记录的可行答案 ans = 2,就是 √8 的整数部分。

不必在数组里二分——只要「答案越大越满足/越不满足」,就能直接在答案范围里二分。爱吃香蕉、分割数组都是它。

参考代码(Python)

Python
1l, r, ans = 0, x, 0
2while l <= r:
3    mid = (l + r) // 2
4    if mid * mid <= x:                 # 可行,试更大
5        ans = mid; l = mid + 1
6    else: r = mid - 1                  # 太大,缩小
7return ans

复杂度分析

  • 时间复杂度:O(log x) —— 每次砍一半
  • 空间复杂度:O(1) —— 几个变量

套路模板

记住骨架:可行就记录 ans 并往大走、不可行往小走。求「最小可行」就反过来:可行往小走。

Python
1# 找「最大的满足 check 的值」
2l, r, ans = 最小, 最大, 默认
3while l <= r:
4    mid = (l + r) // 2
5    if check(mid): ans = mid; l = mid + 1   # 可行→记录并求更大
6    else: r = mid - 1
7return ans

易错点

  • mid*mid 溢出(其它语言) → ✅ Python 无忧;C++ 用 long 或比较 mid<=x/mid(大数相乘会溢出 int)
  • 没记录 ans 直接返回 l/r → ✅ 可行时显式 ans=mid(边界返回容易差一,记录最稳)

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →45. 跳跃游戏 II ← 返回题库