进阶之路

首页 新随笔 管理

要求:Implement int sqrt(int x).  Compute and return the square root of x.

解决方法:

1.牛顿法Newton's method

 化解:计算  x2 = a 的解,令 y = x2 - a,相当于求解 y = 0 的解,f(x) 如图。


   第一步:取 x0 = a / 2 , 如果  x0 不是解,在点( x0,y0) 做切线 y - y0 = (x - x0) * y'0 ,与 x 轴的交点为 x1 = x0 - y0 / y'0 = x0 - (x02 - a) / (2x0) = (x0 + a / x0) / 2 

  第二步:如果 x1 不是解,做一个经过  ( x1,y1) 这个点的切线,与x轴的交点为 x2

…………

结束条件:

a.  f( xi ) ≈ 0;

b. xi xi-1.

代码:

 

inline double ABS(double x){
    return x > 0 ? x : (-1 * x);
}

class Solution {
public:
    int sqrt(int x) {
        /* 用牛顿迭代法求浮点数的平方根 */  
        double g0 = 0, g1 = x;   
        while(ABS(g1-g0) > 0.9)   
        {   
            g0 = g1;   
            g1 = (g0 + (x / g0)) / 2;
        }   
        return floor(g1); // (int)g1
    }
};

 

 2. 分治法Divide and conquer

a = 0 时,返回 0. 

a = 1 时,返回 1.

a > 1 时,返回的数在序列 1 与 a/2 之间,序列有序,所以可以用二分法查找。

代码如下:

class Solution {
public:
   int sqrt(int x){
       /***********  二分法  ************/
       /*********************************/
       if(x == 0) return 0;
       if(x == 1) return 1;
       unsigned long long begin = 1, end = x >> 1;
       while(begin < end)
       {
            unsigned long long mid = (begin + end) >> 1;
            unsigned long long  tem = mid * mid;
            if(tem == x) return mid;
            else if(tem > x) end = mid -1;
            else begin = mid + 1;
       }
       if(begin = end)
       {
          unsigned long long tem = end * end;
          if(tem <= x) return end;
          if(tem > x)  return end - 1;
       }
       else return end;
    }
};

 

3. 构造数字

从高位到低位,依次试探添加 1。

class Solution {
public:
    int sqrt(int x) {
        int ans = 0;
        int bit = 0X40000000;
        while(bit > 0) {
            ans |= bit;
            if (ans > x / ans) {
                ans ^= bit;
            }
            bit >>= 1;
        }
        return ans;

    }
};

 

 

 

posted on 2014-03-22 18:43  进阶之路  阅读(777)  评论(0编辑  收藏  举报