掘金团队号上线,助你 Offer 临门! 点击 查看详情
x 的平方根(题号69)
题目
实现int sqrt(int x)
函数。
计算并返回 x
的平方根,其中 x
是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
链接
解释
主要就是二分查找,由于自己对二分查找的理解不到位,写出来的代码有些丑陋,但出奇的是性能竟然比正统的二分查找好一些,可能是由于多了一步的判断,减少了一些运算过程。
另外一种牛顿查找就直接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:想查看往期文章和题目可以点击下面的链接:
这里是按照日期分类的👇
经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇
有兴趣的也可以看看我的个人主页👇