算法题-数组-69- x 的平方根

131 阅读1分钟

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。

最后返回一个整数即可

image.png