【JAVA算法】简单-x 的平方根

算法虽难,循序渐进,督促自己,总有进步;
本博文仅为了督促自己学习算法,如有遗漏或错误之处,请不吝指教;

题目

实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2

示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。

解题方案:

1.使用JAVA API简单方法

算法思路

JAVA有提供相关API

  • (int) Math.sqrt(x)

2.暴力法

采用性能最差的逐步对比计算

JAVA代码

public int mySqrt(int x) {
    if (x < 2) return x;
    int i=1;
    while (i*i<=x){
	   if(i*i<=0) break;
	   i++;
    }
    return --i;
  }

复杂度

  • 时间复杂度:O(N)

存在问题

如果输入的数字很大,该方法的效率非常低

2.袖珍计算器算法

算法思路

通常,袖珍计算器通过对数表或其他方式计算指数函数和自然对数。那么考虑将求平方根的运算转换为指数运算和对数运算:
在这里插入图片描述
此方法中使用到了对数表与其他策略,省略了一部分计算。但实际上对数函数和指数函数本身就是这样计算的。

JAVA代码

public int mySqrt(int x) {
    if (x < 2) return x;

    int left = (int)Math.pow(Math.E, 0.5 * Math.log(x));
    int right = left + 1;
    return (long)right * right > x ? left : right;
  }

复杂度

  • 时间复杂度:O(1)。
  • 空间复杂度:O(1)。

3.二叉查找

算法思路

当 x≥2 时,它的整数平方根一定小于 x/2 且大于 0,即 0

【JAVA算法】简单-x 的平方根_第1张图片
步骤:

  • 如果 x < 2,返回 x
  • 令左边界为 2,右边界为 x / 2
  • 当 left <= right 时:
    令 num = (left + right) / 2,比较 num * num 与 x:
    如果 num * num > x,更新右边界为 right = pivot -1。
    如果 num * num < x,更新左边界为 left = pivot + 1。
    如果 num * num == x,即整数平方根为 num,返回 num
  • 返回 right

JAVA代码

public int mySqrt(int x) {
    if (x < 2) return x;
    long num;
    int pivot, left = 2, right = x / 2;
    while (left <= right) {
      pivot = left + (right - left) / 2;
      num = (long)pivot * pivot;
      if (num > x) right = pivot - 1;
      else if (num < x) left = pivot + 1;
      else return pivot;
    }
    return right;
  }

复杂度

  • 时间复杂度:O(logN)
  • 空间复杂度:O(1)

4.牛顿法

算法思路

计算平方根,最好和使用最多的方法是牛顿法,这里使用不带种子修剪版本的牛顿法简化此问题

不讨论其数学证明,直接使用牛顿法结论。
【JAVA算法】简单-x 的平方根_第2张图片
如果 x0 = x则收敛到 x平方根

最后当x0和x1在同一整数区间时结束迭代。

JAVA代码

public int mySqrt(int x) {
    if(x < 2){
        return x;
    }
    double x0 = x;
    double x1 = (x0 + x/x0)/2;
    while(Math.floor(x0) != Math.floor(x1)){
        x0 = x1;
        x1 = (x0 + x/x0)/2; 
    }
    return (int)x0;
}

复杂度

  • 时间复杂度:O(logN),此方法是二次收敛的
  • 空间复杂度:O(1)

比较方法二、三、四
这三种方法的时间复杂度都是O(logN),但它们的性能并不相同。

哪种方法执行的迭代次数更少?

由比较每种方法在同一范围下的迭代次数可知,牛顿法的性能最好。
【JAVA算法】简单-x 的平方根_第3张图片

欢迎关注我的公众号,每日更新,督促自己进步

你可能感兴趣的:(算法)