来源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 15
| public 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; int ss = x / (mid + 1); if (x / s == s) return s; if (s > mid && ss < mid + 1) return mid; 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 15
| public 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 18
| class 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); } } }
|