LeetCode 0069

69. Sqrt(x)

原题链接

我的思路:

这题应该用牛顿迭代法就好了。

牛顿迭代法的伪码大概描述一下就是:

要求 sqrt(a)

x1=a/2,xn+1=(xn+axn)/2

直到 xn xn+1 的差足够小。

在这里我直接取整返回。

我的代码:

class Solution {
public:
    int mySqrt(int x) {
        if(x == 0) {
            return 0;
        }
        double t1 = x / 2.0;
        double t2 = (t1 + x / t1) / 2;
        while(fabs(t1 - t2) > 0.001) {
            t1 = t2;
            t2 = (t1 + x / t1) / 2;
        }
        return int(t2);
    }
};

最快解法的代码:

class Solution {
public:
    int mySqrt(int x) {
        if(x<2) return x;
        int y=x/2;
        while(y>x/y) {
            y=(y+x/y)/2;
        }
        return y;
    }
};

应该说也是用的牛顿迭代法,但是相比浮点数运算,整数运算要快一点,所以速度会快一点。

但是我看了这个解法,并没有办法一下感受到这个解法的正确性,也就是while的条件为什么可以那么取,因此我决定证明一下。这里给出一个比较粗略的证明。注意一下,下面的除法都是c++的整数除法。

y=x/2

(x1)2/4y2x2/4

显然我们可以看出 y2=O(x2) ,也就是当 x 足够大的时候,必定有y2>x

因此while的起始条件成立。

y>x/y

y+x/y<y+y

y 是递减的,因此是可以找到出口的

至于为什么这个出口是对的,应该要去看牛顿迭代法的证明吧。。。

x <script type="math/tex" id="MathJax-Element-13">x</script> 比较小的情况,应该枚举一下就可以得到正确性了。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值