leecode算法平方根详解有注释,简单明了。
原题内容
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842…,
由于返回类型是整数,小数部分将被舍去。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sqrtx
方法一》二分法(直接上算法,写的啰嗦但是通俗易懂)
// An highlighted block
public class ProRpcService {
private static double ERR = 1e-7;
public static void main(String[] args) {
System.out.println(squareRoot(16));
System.out.println(Math.sqrt(16));
}
private static double squareRoot(double t) {
// 定下边界
double low = 0;
// 定上边界
double high = t;
// 定上中间值 需要数学基础 2个数的中间值是(a+b)/2;
double mid = (low + high) / 2;
// 传进来的值如果是0和1的情况
if (t < 0) {
throw new RuntimeException("Negetive number cannot have a sqrt root.");
}
if (t == 1) {
return 1;
}
// 判断中间值的平方与T的大小
double a = mid * mid - t;
// 循环和误差值比较 必须用a的绝对值进行比较
while (Math.abs(a) > ERR) {
// 差值大于0 就将中间值赋值给 上边界 再求 中间值
if (a > 0) {
high = mid;
mid = (low + high) / 2;
a = mid * mid - t;
} else {
// 差值大于0 就将中间值赋值给 下边界 再求 中间值
low = mid;
mid = (low + high) / 2;
a = mid * mid - t;
}
}
return mid;
}
}
循环的拆解。其实就是二分法 ,每次循环之后的变量值
方法二》牛顿迭代法(简单粗暴)
数学导论,这个确实难,也感觉到了牛顿的牛皮。按道理说牛顿迭代法,可以计算任何数字的N方根。
// An highlighted block
public class ProRpcService {
private static double ERR = 1e-7;
public static void main(String[] args) {
System.out.println(squareRoot(16));
System.out.println(Math.sqrt(16));
}
private static double squareRoot(double t) {
// 定义一个初始值。
double x0 = 1;
// 求X0斜率的方程式 y=kx+b 知道斜率 可以求得方程 当Y=0是 就是X1的值
double x1 = x0 - (x0 * x0 - t) / (2 * x0);
// 判断结果是否与T在误差范围内
while (t - x1 * x1 > ERR || t - x1 * x1 < -ERR ) {
x0 = x1;
x1 = x0 - (x0 * x0 - t) / (2 * x0);
}
return x1;
}
}
自己在纸张上推断的算法