如何求解整數平方根

求解一個整數的平方根最簡單的辦法就是用庫函數。

但是如何不用庫函數就求解呢?

1. 二分法

我們都知道5的平方根是2.236。如果要求對平方根取整,那麼就是2,我們的目的就是在{1,2,3,4,5}這樣一個數組中找到2。

這是一個典型的查找的需求,我第一時間想到的查找算法就是二分法。

設left=1,right=5,那麼第一趟的mid=3,mid^2=9,大於right,因此我們需要將right左移到mid位置來;

第二趟的left=1,right=3,mid=2,此時mid^2 = 4,基本上接近了,因此判斷一下(mid+1)^2,發現9>5,這就能斷定出5的平方根取整就是2了,直接返回。

下面是代碼的實現:

class Solution {
public:
    /**
     * 
     * @param x int整型 
     * @return int整型
     */
    int sqrt(int x) {
        // write code here
        if (x<=0) return 0;
        int left = 1;
        int right = x;
        
        while (left < right)
        {
            long mid = (left+right)/2;
            if (mid*mid > x) 
            {
                right = mid;
            } 
            else if (mid * mid <= x && (mid+1) * (mid+1) > x)
            {
                return mid;
            }
            else 
            {
                left = mid;
            }
        }
        return left;
    }
};

二分法的時間複雜度是O(logN),執行時間也不差:

只用了3ms。

牛頓迭代公式

用牛頓迭代公式求解平方根基本上相當於殺雞用牛刀。

我們知道平方根實際上就是這樣的一個函數:f(x)=x^2-n=0,其實就是求n的過程。

牛頓迭代公式是這樣的:

x = x- f(x)/f'(x)

所以帶入之前的f(x),我們就能知道求解平方根不過是求解一個公式罷了:

x = x - (x - n/x)/2,其中n是常數。

寫成代碼就是這樣的:

class Solution {
public:
    /**
     * 
     * @param x int整型 
     * @return int整型
     */
    int sqrt(int x) {
        // write code here
        double x1=1, x2=0;
        while (abs(x2-x1)> 1e-8)
        {
            x2=x1;//x2用於記錄上一次迭代的結果
            x1 = (x1 + x/x1)/2;
        }
        return (int) x1;
    }
};

這個效率就差點了:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章