[Leetcode] 69. x 的平方根 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Acceml
V2EX    程序员

[Leetcode] 69. x 的平方根

  •  
  •   Acceml
    Acceml 2018-09-15 23:37:30 +08:00 4328 次点击
    这是一个创建于 2594 天前的主题,其中的信息可能已经有所发展或是发生改变。

    题目

    实现 int sqrt(int x) 函数。

    计算并返回 x 的平方根,其中 x 是非负整数。

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

    示例 1:

    输入: 4 输出: 2 

    示例 2:

    输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 

    由于返回类型是整数,小数部分将被舍去。

    题解

    方法一:二分查找

    找到中间的数: mid = start + (end - start) / 2 而且: mid * mid <= x && (mid + 1) * (mid + 1) > x 但是这么写超出了 Integer 的范围了:

    class Solution { public int mySqrt(int x) { if (x == 0) return 0; int start = 1, end = x; while (start < end) { int mid = start + (end - start) / 2; if (mid * mid <= x && (mid + 1) * (mid + 1) > x)// Found the result return mid; else if (mid > x / mid)// Keep checking the left part end = mid; else start = mid + 1;// Keep checking the right part } return start; } } 

    所以改变一下: mid * mid <= x && (mid+1)(mid+1) > x 下面的 code 为 AC 版本:

    class Solution { public int mySqrt(int x) { if (x == 0) return 0; int start = 1, end = x; while (start < end) { int mid = start + (end - start) / 2; if (mid <= x / mid && (mid + 1) > x / (mid + 1))// Found the result return mid; else if (mid > x / mid)// Keep checking the left part end = mid; else start = mid + 1;// Keep checking the right part } return start; } } 

    python 版本

    class Solution: def mySqrt(self, x): start, end = 0, x while start <= end: # 结果都计算为整数 mid = start + (end - start) // 2 if mid * mid <= x < (mid + 1) * (mid + 1): return mid elif x < mid * mid: end = mid else: start = mid + 1 

    牛顿迭代法

    基本思想:把非线性方程线性化,用线性方程的解逐步逼近原方程的解

    求某个数(比如 8)的平方根其实就是求解 f(x) = x^2 - 8 = 0 的解

    如上图

    点(x[k+1], 0)满足该方程 0 = f ( x[k]) + f'(x[k])(x[k+1] - x[k]) 得到牛顿迭代法的迭代公式:

    x[k+1] = x[k] - f(x[k]) / f'(x[k])

    回到求 8 的平方根

    x[k+1] = x[k] - (x[k] - 8) / (2 * x[k]) = (x[k] + 8 / x[k]) / 2

    就这样一直逼近到 x[k] * x[k] <= 8

    class Solution { public int mySqrt(int x) { if (x == 0) return 0; long i = x; while(i > x / i) i = (i + x / i) / 2; return (int)i; } } 

    python 版本

    class Solution: def mySqrt(self, x): """ :type x: int :rtype: int """ if x == 0: return 0 i = x while int(i) > int(x / i): i = (i + x / i) / 2 return int(i) 

    热门文章

    14 条回复    2018-09-25 00:41:21 +08:00
    Kilerd
        1
    Kilerd  
       2018-09-15 23:42:50 +08:00
    又来误人子弟了吗?
    easylee
        2
    easylee  
       2018-09-15 23:46:38 +08:00 via Android
    @Kilerd 此话怎讲?这里面有什么故事吗?
    zhuangzhuang1988
        3
    zhuangzhuang1988  
       2018-09-15 23:50:37 +08:00
    sicp 101
    broadliyn
        4
    broadliyn  
       2018-09-16 02:57:26 +08:00 via iPhone
    这种求近似解的
    高数里边极限等价替代、微分、泰勒公式套一下不就好啦。
    broadliyn
        5
    broadliyn  
       2018-09-16 03:07:22 +08:00 via iPhone
    也可以根据单调连续的函数零点左右的两个值乘积为负的特性再配合二分法可以逼出近似解。
    broadliyn
        6
    broadliyn  
       2018-09-16 03:16:45 +08:00 via iPhone
    除了上边的二分法,还有切线法,也就是 lz 的解法,没有 latex 排版表示看不懂 lz 在写什么。
    此外还有割线法,如果原函数的导数复杂的话,可以用割线来近似替代切线。

    上述出处是高数上册,微分中值定理与导数的应用里的泰勒公式、方程的近似解两章。
    RqPS6rhmP3Nyn3Tm
        7
    RqPS6rhmP3Nyn3Tm  
       2018-09-16 03:39:21 +08:00 via iPhone
    @Kilerd 解法没错,而且牛顿法很难想到,效率也很高
    puyo
        8
    puyo  
       2018-09-16 09:07:49 +08:00 via Android
    用雷神之锤法可不可以
    zingl
        9
    zingl  
       2018-09-16 12:01:19 +08:00
    aliipay
        10
    aliipay  
       2018-09-16 15:55:32 +08:00
    @puyo 我在自己机器上跑可以,是牛顿迭代法的 10 倍。 放到 leetcode 就执行出错
    CSM
        11
    CSM  
       2018-09-16 17:43:54 +08:00 via Android
    @puyo 我看到这个题第一个想到的就是雷神之锤
    Acceml
        12
    Acceml  
    OP
       2018-09-16 22:55:45 +08:00
    @Kilerd 你最正确,也最厉害,你尽管 diss,然而我并不 care 你...
    ayyll
        13
    ayyll  
       2018-09-16 23:14:43 +08:00 via Android
    为啥要发这里呀。。。还不如找个 oi 或者 acm 群水呢 。。这里的人都对解题报告这种东西不感冒吧
    20015jjw
        14
    20015jjw  
       2018-09-25 00:41:21 +08:00 via Android   1
    @easylee 他之前写了个很烂的答案.. 然后还强行 defend.. 喷点主要是名企们看到那个答案肯定没 offer..
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3912 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 10:15 PVG 18:15 LAX 03:15 JFK 06:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86