来自北大算法课的Leetcode题解:69. x的平方根

代码仓库Github | Leetcode solutions @doubleZ0108 from Peking University.

  • 解法1(爆内存): 依次循环直到 i 2 < t a r g e t < ( i + 1 ) 2 i^2 < target < (i+1)^2 i2<target<(i+1)2
    • 这里如果用乘法容易int溢出,用除法就会避免
    • 改进(T57% S83%):可以从1~x/2二分查找降复杂度
  • 解法2(T80% S98%): 牛顿迭代法

【牛顿迭代法】

Untitled.png

平方根相当于求解 x 2 = n    ⟺    f ( x ) = x 2 − n x^2 = n \iff f(x) = x^2-n x2=nf(x)=x2n的解,牛顿迭代法从一个很大的数开始,不断做函数切线,取切线于x轴交点不断迭代

x i x_i xi处的切线方程 f ( x i ) + f ′ ( x i ) ( x − x i ) = 0 f(x_i) + f'(x_i)(x-x_i) = 0 f(xi)+f(xi)(xxi)=0

解方程得 x = x i 2 + n 2 x i x = \frac{x_i^2 + n}{2x_i} x=2xixi2+n

终止条件是 x , x i x, x_i x,xi足够近,对于整数问题就是判断这两个数是不是差了1


或者可以通过泰勒函数展开来求近似解,本质是一样的

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        if x < 2:   # 0, 1
            return x

        # 解法2
        t = x
        while t > x//t:
            t = (t**2 + x) // (2*t)
        return t
    
    def otherSolution(self, x):
        if x < 2:
            return x

        # 解法1: 直接顺序解会爆内存
        for i in range(1, x//2+1):
            if i*i <= x and (i+1)*(i+1) > x:
                return i

        # 解法1 改进
        i, j = 1, x//2+1
        while i<=j:
            mid = (i+j)//2
            if mid**2 <= x:
                i = mid + 1
            else:
                j = mid - 1
        return (i+j)//2
# 标准的牛顿法
root = x/2
for _ in range(20):  # 迭代20次
	root = (1/2) * (root + (x/root))
return root
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

doubleZ0108

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值