69- x 的平方根
题目描述
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
示例 1:
输入: x = 4
输出: 2
示例 2:
输入: x = 8
输出: 2
解释: 8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
提示:
0 <= x <= 231 - 1
分析
题中描述的意思可以理解为找到一个整数b,满足 b^2 <= x 且 (b+1)^2 > x
可以考虑二分法
题解
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
let left=1, right=x;
while(left<=right) {
let center = left + ((right-left) >> 1);
let double = center * center;
if(double==x) {
return center;
} else if(double<x) {
left = center + 1;
} else {
right = center -1;
}
}
return left + ((right-left) >> 1)
};
这里需要考虑溢出的问题,所以可以考虑使用位运算。
分析
时间复杂度:O(log n)
空间复杂度:O(1)
难点
区间划分,边界条件
优化 - 牛顿迭代法
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
let r = x
while (x / r < r ) r = ((r + x / r) / 2) | 0
return r
};
这里考虑的是如果目标值是a我们要求的是x=sqrt(a)的话(与代码中不同),也就是解 x^2-a=0 的解,也就是 y=x^2-a 与 x 轴的非负交点 A(sqrt(a), 0) 。
我们首先把x的值就赋值为a,很明显 x^2 > a。
此时,我们把求出来y=x^2-a曲线的切线,它与x轴的交点B更靠近A。y曲线的切线的斜率为2x,可以得到。接下来我们通过 x−f(x)/(2x) 就是一个比 x 更靠近 A 点的横坐标,也就是 ( x + a / x ) / 2。
最后返回一个整数即可