前端刷题路-Day16|刷题打卡

463 阅读2分钟

掘金团队号上线,助你 Offer 临门! 点击 查看详情

x 的平方根(题号69)

题目

实现int sqrt(int x) 函数。

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

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

示例 1:

输入: 4
输出: 2

示例 2:

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

链接

leetcode-cn.com/problems/sq…

解释

主要就是二分查找,由于自己对二分查找的理解不到位,写出来的代码有些丑陋,但出奇的是性能竟然比正统的二分查找好一些,可能是由于多了一步的判断,减少了一些运算过程。

另外一种牛顿查找就直接GG了,这题真不会啊。

自己的答案(二分查找)

var mySqrt = function(x) {
  var left = 0
      right = x
  while (left <= right) {
    var mid = parseInt((left + right) / 2)
    if (mid * mid === x) {
      return mid
    } else if (mid * mid < x && (mid + 1)*(mid + 1) >x) {
      return mid
    } else if (mid * mid < x) {
      left = mid + 1
    } else {
      right = mid - 1
    }
  }
};

上面这种解法其实是利用了题目的特点,比普通的二分查找多了一层判断条件。

因为只要取整就行,所以当mid的平方小于x,同时mid+1的平方大于x就行了,此时可以直接返回mi d,后续的步骤就不需要了。

更好的方法(二分查找)

var mySqrt = function(x) {
  var left = 0
      right = x
      res = null
  while (left <= right) {
    var mid = ~~((right - left) / 2) + left
    if (x / mid === mid) {
      return mid
    } else if ( x / mid > mid ) {
      left = mid + 1
      res = mid
    } else {
      right = mid - 1
    }
  }
  return res
};

正常的二分查找,没啥可说的。之所以不用mid*mid而是用x/mid,是怕有的数字太大会超出JS最大安全数,导致程序GG,除就不会有这种问题了。

这个条件比我写的方法少了一步,但比我写的多了一个res,这就是了,我直接把结果写到条件里,这样就不用等待while执行完才能返回,只要满足条件即可,这两种方法我个人觉得都可以,不过这种方法更符合二分查找的规范,代码非常符合模板标准,我这就稍微改善了一下。

更好的方法(牛顿迭代)

var mySqrt = function(x) {
    // 解法二 数学方法 牛顿迭代 公式 r = ( r + x / r ) / 2
    let r = x

    while (r ** 2 > x) r = ((r + x / r) / 2) | 0

    return r
};

这题超纲了,真不会啊,利用一个数学公式,不断迭代即可拿到最终结果。



PS:想查看往期文章和题目可以点击下面的链接:

这里是按照日期分类的👇

前端刷题路-目录(日期分类)

经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇

前端刷题路-目录(题型分类)

有兴趣的也可以看看我的个人主页👇

Here is RZ