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

关于牛顿法, 参见:

公式是: 69. Sqrt(x)*_解决方法 (​​​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;
}
};