来源Leetcode第69题x的平方根
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 2:
输入: 8
输出: 2
不正经解法
最简单的就直接调用Math.sqrt()就行了,但这很明显不符合题意。
代码就一句:1
return (int)Math.sqrt(x);
二分查找
利用x/mid 来比较是否接近目标
代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public int mySqrt(int x) {
if(x == 0 || x == 1) return x;
int l = 0;//左边界
int r = x;//右边界
while (l <= r) {
int mid = (r + l) / 2;
int s = x / mid; //用来判断mid大于目标还是小于目标,或等于目标
int ss = x / (mid + 1);
if (x / s == s) return s; //刚好是他的算术平方根
if (s > mid && ss < mid + 1) return mid; //例如6 在2的平方以及 3的平方之间 答案为2
if (s > mid) l = mid + 1; //调整边界
if (s < mid) r = mid - 1;
}
return 0;
}
当然也有用double类型来提高精度的
代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public int mySqrt2(int x) {
double mid = (double) x / 2;
double left = 0;
double right = x;
while ((int)left <(int) right){
if(mid * mid > x){
right = mid;
mid = (double) (left + right) / 2;
}else {
left = mid;
mid = (double) (left + right) / 2;
}
}
return (int)mid ;
}
牛顿迭代法
来源题解
关于牛顿迭代法
这种算法的原理很简单,我们仅仅是不断用 (x, f(x))的切线来逼近方程 x^2-a=0根。根号 a 实际上就是 x^2-a=0的一个正实根,这个函数的导数是 2x。也就是说,函数上任一点 (x,f(x)) 处的切线斜率是 2x。那么,x-f(x)/(2x)就是一个比 x 更接近的近似值。代入 f(x)=x^2-af得到 x-(x^2-a)/(2x),也就是 (x+a/x)/2。
代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Solution {
int s;
public int mySqrt(int x) {
s=x;
if(x==0) return 0;
return ((int)(sqrts(x)));
}
public double sqrts(double x){
double res = (x + s / x) / 2;
if (res == x) {
return x;
} else {
return sqrts(res);
}
}
}