「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」。
题目
链接:
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
**注意:**不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
示例 1:
输入: x = 4 输出: 2
示例 2:
输入: x = 8 输出: 2 解释: 8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
提示:
0 <= x <= 231 - 1
解题思路
红蓝划分法
var mySqrt = function(x) {
if(x === 0 || x === 1) return x
let l = -1
let r = x
while( l+1 !== r){
let mid = Math.floor((l+r)/2)
if(mid * mid <= x){
l = mid
}else{
r = mid
}
}
return l
};
牛顿迭代
五次及以上多项式方程没有根式解(就是没有像二次方程那样的万能公式),这个是被伽罗瓦用群论做出的最著名的结论。
但是,没有王屠夫难道非得吃带毛猪?工作生活中还是有诸多求解高次方程的真实需求(比如行星的轨道计算,往往就是涉及到很复杂的高次方程),这日子可怎么过下去啊?
没有根式解不意味着方程解不出来,数学家也提供了很多方法,牛顿迭代法就是其中一种。
对于毕业好几年,有点费脑筋
var mySqrt = function(x) {
let n = x
while( n * n > x){
n = Math.floor((n+x/n)/2)
}
return n
};
二分查找,逼近目标值
- 首先是边界情况: 0、1的平方根分别是0、1
- 剩下就是 x>=2 的情况:
- 左右指针指向左右边界
- 求出中位数 mid
- 如果 mid 的平方正好等于 x,则返回 mid
- 如果 mid 的平方小于 x,说明平方根落在 mid 和 right 之间,让 left=mid
- 如果 mid 的平方大于 x,说明平方根落在 left 和 mid 之间,让 right=mid
- 退出循环的条件是左右指针相邻了。它们俩中有一个是平方根。再判断一下就好。
代码
const mySqrt = (x) => {
if (x < 2) return x;
let left = 1;
let right = x >>> 1; // 除以2并取整,缩小一下遍历的范围
while (left + 1 < right) { // 退出循环时,它们相邻
let mid = (left + right) >>> 1;
if (mid == x / mid) {
return mid;
} else if (mid < x / mid) {
left = mid;
} else {
right = mid;
}
}
return right > x / right ? left : right;
};