LeetCode:69. x 的平方根

题目:

69. x 的平方根
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例 1:
输入:x = 4
输出:2

示例 2:

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。

提示:
0 <= x <= 231 - 1

思路:
1.二分法查找

  • 如果这个整数的平方等于输入整数,那么我们找到了这个数
  • 如果这个整数的平方严格大于输入整数,那么肯定不是我们要找的数
  • 如果这个整数的平方严格小于输入整数,那么有可能是我们要找的数

因此可以采用二分查找的方法查找给出数字的算术平方根,需要注意的是在循环里用除法判断防止溢出,而分母不能等于0,所以需要将left从1开始设定,还需要对输入整数是否为0做单独的判断。

代码:

class Solution {
public:
    int mySqrt(int x) {
        if(x == 0) {//不要忘记x==0
            return 0;
        }
        int left = 1;//防止mid等于0
        int right = x;
        while(left <=right) {
            int mid = left + ((right - left)/2);
            if(mid > x / mid)//用除法判断防止溢出
               right = mid - 1;
            else if(mid < x / mid){
                left = mid + 1;
            }
            else
               return mid;

        }
        return right;
    }
};

复杂度分析

  • 时间复杂度O(logx),即为二分查找需要的次数。
  • 空间复杂度O(1)

2.牛顿迭代法

牛顿迭代法(Newton’s Method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson Method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。
LeetCode:69. x 的平方根_第1张图片
LeetCode:69. x 的平方根_第2张图片

由题目给出的条件已知 f(x)=x2-a,根号a是 x2-a=0的正实根,这个函数的导数为 2x,那么 x-f(x)/f’(x) 就是比x更接近的近似值,带入f(x)=x2-af’(x)=2x得到 x-(x2-a)/2x,化简得*(x+a/x)/2*。

代码:

class Solution {
public:
    int mySqrt(int a) {
       if(a == 0)//分母不能为0,所以迭代之前先判断给的数是否为0
          return 0;
       long x = a;
       do {
           x = (x + a/x)/2;
       }while(x * x > a);
       return x;
    }
};

复杂度分析

  • 时间复杂度O(logx),此方法是二次收敛的,相较于二分查找更快。
  • 空间复杂度O(1)

你可能感兴趣的:(LeetCode,c++,leetcode,算法,数据结构)