LeetCode 69. x 的平方根

106 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

一、题目描述:

69. x 的平方根 - 力扣(LeetCode) (leetcode-cn.com)

给你一个非负整数 x ,计算并返回 x 的 算术平方根

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

示例 1:

输入:x = 4
输出:2

示例 2:

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

提示:

  • 0 <= x <= 231 - 1

二、思路分析:

牛顿法固然牛逼,从数学上减少了迭代,但没有考虑计算量。
牛顿法需要计算切线和坐标轴的交点,这个地方的运算量已经抵得上一次普通二分了。
实际操作后,运算时间和原来都是7ms(JAVA)
这里采用一种底层优化计算的方法,可以达到5ms。
下面是普通的二分搜索,计算量基本都在mm这一步(乘法耗时远高于加减法)。
我们这里取r的上限为2^16,这是本解答的特别之处。可见,在整个二分过程中,m通常也是2的幂次或者是几个2的幂次组合。
反映到2进制上,m只有几位上是1。这样在m
m的计算中,要计算的位数就比较少,会很快。从底层优化了运算。

三、AC 代码:

class Solution {
    public int mySqrt(int x) {
        int l = 0;
        int r = 1 << 16; // 特别之处
        while (l < r-1) {
            int m = (l+r)/2;
            if ((long)m*m <= x)
                l = m;
            else
                r = m;
        }
        return l;
    }
}

四、总结:

算法不只是数学问题,还是工程问题。要综合考虑,提高运算速度。

范文参考

【仗剑骑士】C++, 手撕牛顿迭代法+ 速度超过100%用户 - x 的平方根 - 力扣(LeetCode)

【李三十一】四种方法解决 | x 的平方根算法 - x 的平方根 - 力扣(LeetCode)