x 的平方根

782 字
4 分钟
x 的平方根

题目链接:69. x 的平方根 - 力扣(LeetCode)

  • 难度:简单
  • 标签:数学、二分查找

题目描述#

Note

原题说明: 给你一个非负整数 x ,计算并返回 x算术平方根

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被舍去。不允许使用任何内置指数函数和算符(如 pow(x, 0.5))。

示例#

  • 输入: x = 4 -> 输出: 2
  • 输入: x = 8 -> 输出: 2(8 的平方根约为 2.828,舍去小数后得 2)

方案一:线性扫描(初步尝试)#

核心思路: 从小到大尝试每一个整数 ii,直到发现其平方刚好大于 xx。此时 i1i-1 就是我们要找的整数平方根。

源码实现#

class Solution {
public:
int mySqrt(int x) {
if (x == 0) return 0;
if (x == 1) return 1;
int i;
// 注意:为避免 i * i 导致整型溢出,我们使用 x / i 来进行比较
for (i = 1; i < x; i++) {
if (i <= x / i && (i + 1) > x / (i + 1)) {
break;
}
}
return i;
}
};

复杂度分析#

  • 时间复杂度O(x)O(\sqrt{x})。最坏情况下我们需要检查到 x\sqrt{x}
  • 空间复杂度O(1)O(1)

方案二:二分查找(进阶解法)#

核心思路: 由于 xx 的平方根一定落在 [1,x][1, x] 之间,且函数 y=i2y = i^2 在该范围内是单调递增的,因此我们可以使用二分查找来极速定位。

源码实现#

class Solution {
public:
int mySqrt(int x) {
if (x == 0) return 0;
int left = 1, right = x;
while (left < right) {
// 取中点时 +1 是为了在只有两个元素时向上取整,配合 left = mid 避免死循环
int mid = left + (long)(right - left + 1) / 2;
if (mid <= x / mid) {
left = mid; // mid 可能是答案,尝试向右侧逼近
} else {
right = mid - 1; // mid 太大了,缩减右边界
}
}
return left;
}
};

复杂度分析#

  • 时间复杂度O(logx)O(\log x)。对数级别的效率,即使是 23112^{31}-1 级别的数据也能瞬秒。
  • 空间复杂度O(1)O(1)

关键避坑指南#

  1. 防止整型溢出: 在 32 位系统中,如果判断 mid * mid <= x,当 mid 较大时会直接溢出导致逻辑错误。
    • 对策 A:使用 mid <= x / mid(推荐,本项目采用)。
    • 对策 B:将变量声明为 long long
  2. 二分死循环: 当区间缩小到只剩两个元素(如 left=2, right=3)时,如果 mid 总是取下整(left),且代码逻辑中有 left = mid,则会陷入死循环。
    • 对策:使用 left + (right - left + 1) / 2 这种向上取整的计算方式。

总结#

  • 数学与搜索的结合:这道题是二分查找在数学数值逼近领域的经典应用。
  • 工程细节:处理好“除以0”和“溢出”是体现代码健壮性的关键。
Tip

进阶思考:除了二分法,这道题还有一种更高级的解法——牛顿迭代法。它利用切线逼近,收敛速度极快,感兴趣的同学可以查阅相关资料。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

x 的平方根
https://firefly-7a0.pages.dev/posts/leetcode_notes/69sqrtx/
作者
lonelystar
发布于
2025-10-18
许可协议
CC BY-NC-SA 4.0
最后更新于 2025-10-18,距今已过 193 天

部分内容可能已过时

评论区

Profile Image of the Author
LonelyStar
Hello, I'm LonelyStar.
公告
欢迎来到我的博客!
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
119
分类
11
标签
346
总字数
226,548
运行时长
0
最后活动
0 天前

目录