问题概述
给定一个非负整数 x,返回 x 的平方根,向下取整到最近的整数。返回的整数也应该是非负的。
不能使用任何内置的指数函数或运算符。
解法 1:二分搜索
工作原理
使用二分搜索找到平方小于或等于 x 的最大整数:
python
class Solution:
def mySqrt(self, x):
if x < 2:
return x
left = 1
right = x // 2
while left <= right:
mid = left + (right - left) // 2
square = mid * mid
if square == x:
return mid
elif square < x:
left = mid + 1
else:
right = mid - 1
return right
复杂度分析
- 时间复杂度: O(log x) - 每次迭代将搜索空间减半
- 空间复杂度: O(1) - 只使用常数额外空间
何时使用
- 推荐 - 标准方法,易于理解
- 保证 O(log x) 性能
- 处理所有边界情况
解法 2:牛顿法
工作原理
使用牛顿法迭代逼近平方根。公式为:x_{n+1} = (x_n + x / x_n) / 2。从 guess = x // 2 开始可以减少迭代次数:
python
class Solution:
def mySqrt(self, x):
if x < 2:
return x
guess = x // 2
while guess * guess > x:
guess = (guess + x // guess) // 2
return guess
复杂度分析
- 时间复杂度: O(log log x) - 牛顿法二次收敛
- 空间复杂度: O(1) - 只使用常数额外空间
何时使用
- 更快 - 对于大数收敛速度比二分搜索快
- 对于非常大的输入更高效
- 需要理解牛顿法
解法 3:内置函数(不推荐用于力扣)
工作原理
使用 Python 的内置 math.sqrt() 函数。注意:此解法在力扣题目中可能不被允许,因为题目通常要求不使用内置的指数函数。
python
import math
class Solution:
def mySqrt(self, x):
return int(math.sqrt(x))
复杂度分析
- 时间复杂度: O(1) - 硬件操作
- 空间复杂度: O(1) - 只使用常数额外空间
何时使用
- 不推荐用于力扣 - 违反题目约束
- Python 中最简单的解法
- 适用于参考或非竞赛编程场景
对比
| 方法 | 时间 | 空间 | 最佳适用 |
|---|---|---|---|
| 二分搜索 | O(log x) | O(1) | 大多数情况,易于理解 |
| 牛顿法 | O(log log x) | O(1) | 大数,最优性能 |
| 内置函数 | O(1) | O(1) | 仅作参考(力扣不允许) |
总结
二分搜索是查找平方根的标准方法,搜索平方 ≤ x 的最大整数。牛顿法收敛更快(二次收敛),对于大数更高效,但二分搜索更简单直观。两种解法都实现了 O(1) 空间复杂度。