69. x 的平方根
官网上Ac,并不是考察点。
class Solution {
public:
int mySqrt(int x) {
return sqrt(x);
}
};
二分法分析:
对于一个非负数n,它的平方根不会大于(n/2+1)
,画个图
y
=
x
y=\sqrt{x}
y=x和
y
=
1
2
x
y=\frac{1}{2}x
y=21x就知道切点是(1,1)。在[0, n/2+1]这个范围内可以进行二分搜索,求出n的平方根。
[1]注:在中间过程计算平方的时候可能出现溢出,所以用long long
。
写烂二分法。。。。
class Solution {
public:
int mySqrt(int x) {
long long i = 0;
long long j = x / 2 + 1;
while (i<=j)
{
long long mid = (i + j) / 2;
long long sq = mid*mid;
if (sq == x)return mid;
else if (sq < x)i = mid+1;
else j = mid-1;
}
return j;
}
};
方法二牛顿法:
[1] [2] 过程推导。
令
f
(
x
)
=
x
2
−
n
f(x)=x^{2}-n
f(x)=x2−n,
则
x
i
+
1
=
x
i
−
(
x
i
2
−
n
)
/
(
2
∗
x
i
)
=
x
i
−
x
i
/
2
+
n
/
(
2
∗
x
i
)
=
x
i
/
2
+
n
/
2
∗
x
i
=
(
x
i
+
n
/
x
i
)
/
2
x_{i+1}=x_{i} - (x_{i}^2 - n) / (2*x_{i}) = x_{i} - x_{i} / 2 + n / (2*x_{i}) = x_{i} / 2 + n / 2*x_{i} = (x_{i} + n/x_{i}) / 2
xi+1=xi−(xi2−n)/(2∗xi)=xi−xi/2+n/(2∗xi)=xi/2+n/2∗xi=(xi+n/xi)/2.
class Solution {
public:
int mySqrt(int x) {
if (x == 0)return 0;
double res = 1, pre = 0;
while (abs(res - pre) > 1e-6)
{
pre = res;
res = (res + x / res) / 2;
}
return res;
}
};
[1]https://www.cnblogs.com/AnnieKim/archive/2013/04/18/3028607.html
[2]https://en.wikipedia.org/wiki/Newton's_method