69. Sqrt(x)*
https://leetcode.com/problems/sqrtx/
题目描述
Implement int sqrt(int x).
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
Example 1:
Input: 4
Output: 2
Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since
the decimal part is truncated, 2 is returned.
解题思路
思路 1: 二分法, 在 [0, x / 2] 范围内进行搜索, 找到第一个使得 mid * mid > x 的数. 注意 mid * mid 可能越界的问题, 解决方法可以用 long 或 long long, 或者变换成 mid > x / mid.
思路 2: 牛顿法.
C++ 实现 1
这个实现 beats 100%.
使用二分查找可解. 但有个地方必须注意:
判断条件不要写成
if (mid * mid <= x)
而是要写成 if (mid <= x/mid), 因为当 mid 足够大时, mid * mid 超出了 int 能表示的范围.
class Solution {
public:
int mySqrt(int x) {
int l = 1, r = x;
while (l <= r) {
int mid = l + (r - l) / 2;
if (mid <= x/mid)
l = mid + 1; // 注意 l 不是 l++ 变化!!!
else
r = mid - 1;
}
return (l - 1); // 最后 l 找到的是第一个满足 mid * mid > x 的值.
}
};
C++ 实现 2
关于牛顿法, 参见:
- http://www.cnblogs.com/AnnieKim/archive/2013/04/18/3028607.html
- 以及 Wikipedia: https://en.wikipedia.org/wiki/Newton%27s_method
公式是:
x
i
+
1
=
1
2
(
x
i
+
n
x
i
)
x_{i+1} = \frac{1}{2}(x_i + \frac{n}{x_i})
xi+1=21(xi+xin) (n 就是这里的 x)
注意下面代码中, res 设置为 long 是为了防止越界, 因为 res + res / 2 在初始化 res = x 的情况下, 如果 x 刚好为 INT32_MAX, 那么就越界了.
class Solution {
public:
int mySqrt(int x) {
if (x < 1) return 0;
long res = x;
while (res > x / res)
res = (res + x / res) / 2;
return res;
}
};
本文详细解析了LeetCode上的经典题目69.Sqrt(x),提供了两种高效求解平方根的方法:二分法和牛顿法。通过C++代码实现,展示了如何避免整数溢出并达到最优性能。


被折叠的 条评论
为什么被折叠?



