kylin来刷题啦-Day01:69. x 的平方根

239 阅读1分钟

69. x 的平方根

题目描述

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2

示例 2:

输入: 8
输出: 2

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

友情链接

leetcode-cn.com/problems/sq…

思路解析

求 x 的平方根,x 等于什么呢?我们先假设 x 的平方根是 ans, 那么算式就是 ans * ans = x 。结合这道题可以理解成我们的目标就是循环查找,直到找到最大的数,这个数就是 ans 。这道题我采用二分查找法,查找范围是 range[1,x],直至找到最大的边界值。在每一次迭代过程中,都求出中位数 mid 和 x/mid ,通过比较 mid 和 x/mid 来确定下一轮循环的左右边界。

算法实现

class Solution {
    public int mySqrt(int x) {
       int left=1;
       int right=x;
       int ans=0;
       while(left<=right){
           int mid=left+(right-left)/2;
           if(mid<=x/mid){
               left=mid+1;
                ans=mid;
           }else{
               right=mid-1;
           }
       }
       return ans;
    }
}

进阶设计

通过二分查找结合牛顿迭代法来求 x 的平方根。但是在定义变量时需要注意溢出的问题。注意看这里 ans 定义的是 long ,最终结果返回的时候再将 long 强转成 int 。

class Solution {
    public int mySqrt(int x) {
      long ans=x;
      while(ans*ans>x){
          ans=(ans+x/ans)/2;
      }
       return (int)ans;
    }
}

牛顿法的原理可参考下图。

newton.png

一开始随便定义 ans 的值,因为在通过 ans * ans > x 判断后能够迅速缩小查找范围。在有限次迭代求解后 ans 不断逼近 x 的平方根。

运行结果:

第一种二分查找法执行用时 2ms 。内存消耗 35.5MB 。 第二种结合牛顿迭代法执行用时 也是 2ms 。内存消耗 35.6MB 。

可以看出这两种算法在性能上没有什么区别。