zoukankan      html  css  js  c++  java
  • 算法

    [LeetCode(Q69)] Sqrt(x) (编程实现sqrt)

    Q: 

    Implement int sqrt(int x).

    Compute and return the square root of x.

    A:

    这里给出两种实现方法:一是二分搜索,二是牛顿迭代法。

    1. 二分搜索

    对于一个非负数n,它的平方根不会小于大于(n/2+1)(谢谢@linzhi-cs提醒)。在[0, n/2+1]这个范围内可以进行二分搜索,求出n的平方根。

    复制代码
     1 int sqrt(int x) {
     2     long long i = 0;
     3     long long j = x / 2 + 1;
     4     while (i <= j)
     5     {
     6         long long mid = (i + j) / 2;
     7         long long sq = mid * mid;
     8         if (sq == x) return mid;
     9         else if (sq < x) i = mid + 1;
    10         else j = mid - 1;
    11     }
    12     return j;
    13 }
    复制代码

    注:在中间过程计算平方的时候可能出现溢出,所以用long long。

    2. 牛顿迭代法

       为了方便理解,就先以本题为例:

       计算x2 = n的解,令f(x)=x2-n,相当于求解f(x)=0的解,如左图所示。

       首先取x0,如果x0不是解,做一个经过(x0,f(x0))这个点的切线,与x轴的交点为x1

       同样的道理,如果x1不是解,做一个经过(x1,f(x1))这个点的切线,与x轴的交点为x2

       以此类推。

       以这样的方式得到的xi会无限趋近于f(x)=0的解。

       判断xi是否是f(x)=0的解有两种方法:

       一是直接计算f(xi)的值判断是否为0,二是判断前后两个解xi和xi-1是否无限接近。

    经过(xi, f(xi))这个点的切线方程为f(x) = f(xi) + f’(xi)(x - xi),其中f'(x)为f(x)的导数,本题中为2x。令切线方程等于0,即可求出xi+1=xi - f(xi) / f'(xi)。

    继续化简,xi+1=xi - (xi- n) / (2xi) = xi - xi / 2 + n / (2xi) = xi / 2 + n / 2xi = (xi + n/xi) / 2。

    有了迭代公式,程序就好写了。关于牛顿迭代法,可以参考wikipedia以及百度百科

    复制代码
     1 int sqrt(int x) {
     2     if (x == 0) return 0;
     3     double last = 0;
     4     double res = 1;
     5     while (res != last)
     6     {
     7         last = res;
     8         res = (res + x / res) / 2;
     9     }
    10     return int(res);
    11 }
    复制代码

    牛顿迭代法也同样可以用于求解多次方程的解。

    P.S. 本题是求解整数的平方根,并且返回值也是整型。在上述代码基础上稍微做修改,就可以同样适用于double(仅限方法2)。

    复制代码
     1 double sqrt(double x) {
     2     if (x == 0) return 0;
     3     double last = 0.0;
     4     double res = 1.0;
     5     while (res != last)
     6     {
     7         last = res;
     8         res = (res + x / res) / 2;
     9     }
    10     return res;
    11 }
    复制代码
  • 相关阅读:
    sql server 2008数据复制方法
    排错技能:任务管理器中追踪某w3wp.exe是哪个IIS站点的application pool
    SplendidCRM中给来自EditView中的listbox控件设置选中值或数据源
    jQuery String Functions
    [转]jquery getJSON 数据联动(采用序列化和反序列化获取数据) .
    [转]javascript eval函数解析json数据时为什加上圆括号eval("("+data+")")
    深入理解C语言
    Qt回忆录之配置开发环境
    360电话面试
    浅谈C++设计模式之单例模式
  • 原文地址:https://www.cnblogs.com/qlky/p/7735145.html
Copyright © 2011-2022 走看看