开启掘金成长之旅!这是我参与「掘金日新计划 · 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。这样在mm的计算中,要计算的位数就比较少,会很快。从底层优化了运算。
三、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;
}
}
四、总结:
算法不只是数学问题,还是工程问题。要综合考虑,提高运算速度。
范文参考: