x的平方根
力扣----x的平方根算法
题目如下:
思路:
- 暴力法----一个一个列举
- 二分法----用零点定理,如果有一个连续的
f(x)
,且在区间[a, b]
里,f(x)=0
存在一个实数解,我们就可以在区间[a, b]
逐渐逼近实数解
- 首先,
f(a) * f(b) < 0
; - 其次,求一个
mid = (b - a) / 2
; - 然后,去比较是①
f(a) * f(mid) < 0
,还是②f(mid) * f(b) < 0
; - 最后,区间缩小,如果是①,区间为
[a, mid]
,如果是②,区间为[mid, b]
;
- 牛顿迭代法
构建一个函数f(x) = x^2 - C
;然后我们就是在求解一个零点问题
图片为我们展示了我们如何去求解零点
我们需要给定一个初始点x0,然后用这个初始点去逼近零点,这里的计算全是有小数的;我们的条件有两个f(x) = x^2 - C; f'(x) = 2*x;
接下来就是把经过初始点的切线求出来,切线:y = kx + b; 利用(x0, f(x0))
k = 2*X0
b = f(x0) - 2*(x0)*(x0)
y = 2*(x0)*x + f(x0) - 2*(x0)^2
另切线y = 0;
0 = 2*(x0)*(x1) + f(x0) - 2*(x0)^2
x1 = x0 - f(x0) / 2*x0;
x1 = x0 - ((x0)^2 - C) / 2*x0;
x1 = x0 - (x0 - C / x0) / 2;
......
推广至n
xn+1 = xn - (xn - C / xn) / 2;
其他的f(x),xn+1 =xn - f(xn)/ f'(xn);
class Solution {
public:
int mySqrt(int x) {
// 牛顿迭代法
if (0 == x) return 0;
double x0 = x / 2.0;
double xt;
while (true) {
xt = x0 - (x0 - (double(x) / x0)) / 2.0;
if (abs(xt - x0) < 1.0e-10) //前后两次计算的差距小于1 * 10^-10
return xt;
x0 = xt;
}
//二分法
// if (0 == x) return 0;
// int left = 1;
// int right = x;
// int mid = (left + right) / 2;
// while(left + 1 < right) {
// int y_left = left * left - x;
// int y_right = right * right - x;
// int y_mid = mid * mid - x;
// //y_left * y_mid < 0
// if ((y_left > 0 && y_mid < 0) || (y_left < 0 && y_mid > 0)) right = mid;
// //y_right * y_mid < 0
// else if ((y_right > 0 && y_mid < 0) || (y_right < 0 && y_mid > 0)) left = mid;
// else if (y_right * y_mid == 0 || y_left* y_mid == 0) return mid;
// mid = (left + right) / 2;
// }
// return left;
//暴力法
// if (0 == x) return 0;
// for (int n = 1; n < x; n++) {
// if (n*n < x) continue;
// else if (n*n > x) return n - 1;
// else if (n*n == x) return n;
// }
// return 1;
}
};