leetcode 69. x 的平方根
问题描述
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
问题分析
方法一是使用牛顿法,设\(f(x) = x^2 - a, f(x0) + f'(x0)(x-x0) = 0\),则\(x = (x0*x0+a)/(2*x0)\).
方法二是使用二分法,如果mid*mid=x,则mid即为所求,如果mid*mid<x并且(mid+1)*(mid+1)>x,则根据规则mid即为所求,如果mid*mid>x,则中间值过大,right=mid-1,如果mid*mid<x并且(mid+1)*(mid+1)<x,则mid值过小,left=mid+1.
注意一个技巧是如果\(0\leq x \leq 1,z\in \mathbb{Z}\),则\(\sqrt x=x\), 如果\(2\leq x \leq 3\),则\(\sqrt x = 1\),如果\(x \geq 4, x \in \mathbb{Z}\), 则 \(\sqrt x \leq x/2\).
代码1
class Solution {
public:
int mySqrt(int x) {
if(x <= 1) return x;
//else if(1 < x && x < 4) return 1;//这一步可以注释掉,因为2<=x<=3时,\sqrt{x}=1=x/2
long x0 = x/2;
while(x0*x0 > x)
{
x0 = (x0*x0 + x)/(2*x0);
}
return x0;
}
};
结果1
执行用时 :0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗 :8.1 MB, 在所有 C++ 提交中击败了81.46%的用户
代码2
class Solution {
public:
int mySqrt(int x) {
if(x <2) return x;
int left = 1,right = x/2;
long middle,tmp1,tmp2;
while(left <= right)
{
middle = left + (right - left)/2;
tmp1 = middle*middle;
tmp2 = (middle+1)*(middle+1);
if(tmp1 == x)break;
else if(tmp1 < x && tmp2 > x)break;
else if(tmp1 > x) right = middle - 1;
else left = middle + 1;
}
return middle;
}
};
结果2
执行用时 :4 ms, 在所有 C++ 提交中击败了84.10%的用户
内存消耗 :8.3 MB, 在所有 C++ 提交中击败了17.31%的用户