本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
输入: x = 8
输出: 2
解释: 8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
题目解析
思路一
取一个近似值 middle, 一般等于 x / 2,然后不断更新 middle,令 middle 等于 middle 和 x/middle 的平均数,结果和上一次差值小于某个值(我这里取的是 0.1)时,就可以认为这个 middle 是结果。
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
if (x <= 1) return x
let prev = x / 2,
current = NTMethod(x, prev)
while(prev - current > 0.1) {
prev = current
current = NTMethod(x, prev)
}
return Math.floor(current)
};
function NTMethod(x, middle) {
return (middle + x / middle) / 2
}
思路二
我们判断一下平方根是不是自己,如果是自己就返回,0和1的平方根就是自己,然后再定义一个中位数,如果中位数西小于当前目标值,则向左缩小范围,否则向右缩小范围,在进行递归,继续在已经缩小范围内里继续查找,直到值小于1时结束
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
if (x == 0 || x == 1) return x
var find = function (left, right, x) {
if (right - left <= 1) return left;
var mid = Math.floor((right + left) / 2)
mid * mid > x?( right = mid ):(left = mid)
return find(left, right, x)
}
return find(1, x, x)
};
思路三
由于结果只需要整数,所以直接 Math.floor 一下 mid,尽量避免浮点数预算,在判断 mid 的平方是否
<= x以及判断mid + 1的平方是否>x
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
if (x === 1 || x === 0) {
return x
}
let low = 1, high = x, mid = Math.floor(low + (high - low)/2)
while (!(x - Math.pow(mid, 2) >= 0 && x - Math.pow(mid + 1, 2) < 0)) {
if (Math.pow(mid, 2) < x) {
low = mid
} else {
high = mid
}
mid = Math.floor(low + (high - low)/2)
}
return mid
};