这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战
题目描述
给一个不是负数的整数,计算出它的平方根,并返回。如果得到的是小数,则最需要把整数部分返回。
举个例子:
整数: 2
输出: 1
整数: 4
输出: 2
整数: 9
输出: 3
整数: 30
输出: 5
思路分析
第一种方法
我们可以使用Math的现成方法,sqrt方法,这个是来求大于等于0的数字的平方根。如果是负数,则返回NaN。
然后这个返回的数字有可能是有小数的,所以我们可以使用Math.floor方法,取整。
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
return Math.floor(Math.sqrt(x))
};
如果不使用Math的现成方法,能实现取x的平方根吗?
答案是可以的。
第二种方法
求x的平方根,那么就是平方根乘以平方根可以得到x。我们可以利用while循环遍历,如果两个数相乘大于x,那么就证明这个数是x的平方根取整后的数了。
代码如下:
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function (x) {
let num = 1
while (num * num <= x) {
num++
}
return num - 1
};
第三种方法
上面的方法可以是可以,但是需要从1开始逐渐递增,效率相对还是慢了些。
第三种方法可以使用二分法,默认1为左边数。右边数是参数x除以2,一般数的平方根都会比数除以2还小(从4开始)
中间数是左边数加上(右边数减去左边数后再除以2),然后取整赋值给中间数。
- 如果中间数乘以中间数大于右边数,则需要中间数需要减一赋值给右边数。
- 如果中间数乘以中间数等于x,则直接返回中间数
- 如果中间数乘以中间数小于右边数,则需要中间数需要加一赋值给左边数。
最终循环直到左边数大于右边数才终止,最后返回右边数。
代码如下:
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function (x) {
if (x === 1) return x
let left = 1
let mid
let right = Math.floor(x / 2)
while (left <= right) {
mid = Math.floor(left + (right - left) / 2)
if (mid * mid === x) return mid
if (mid * mid > x) {
right = mid - 1
} else {
left = mid + 1
}
}
return right
}