1. 程式人生 > >[LeetCode] Valid Perfect Square 檢驗完全平方數

[LeetCode] Valid Perfect Square 檢驗完全平方數

Given a positive integer num, write a function which returns True if num is a perfect square else False.

Note: Do not use any built-in library function such as sqrt.

Example 1:

Input: 16
Returns: True

Example 2:

Input: 14
Returns: False

Credits:
Special thanks to @elmirap for adding this problem and creating all test cases.

這道題給了我們一個數,讓我們判斷其是否為完全平方數,那麼顯而易見的是,肯定不能使用brute force,這樣太不高效了,那麼最小是能以指數的速度來縮小範圍,那麼我最先想出的方法是這樣的,比如一個數字49,我們先對其除以2,得到24,發現24的平方大於49,那麼再對24除以2,得到12,發現12的平方還是大於49,再對12除以2,得到6,發現6的平方小於49,於是遍歷6到12中的所有數,看有沒有平方等於49的,有就返回true,沒有就返回false,參見程式碼如下:

解法一:

class Solution {
public:
    bool isPerfectSquare(int
num) { if (num == 1) return true; long x = num / 2, t = x * x; while (t > num) { x /= 2; t = x * x; } for (int i = x; i <= 2 * x; ++i) { if (i * i == num) return true; } return false; } };

下面這種方法也比較高效,從1搜尋到sqrt(num),看有沒有平方正好等於num的數:

解法二:

class Solution {
public:
    bool isPerfectSquare(int num) {
        for (int i = 1; i <= num / i; ++i) {
            if (i * i == num) return true;
        }
        return false;
    }
}; 

我們也可以使用二分查詢法來做,要查詢的數為mid*mid,參見程式碼如下:

解法三:

class Solution {
public:
    bool isPerfectSquare(int num) {
        long left = 0, right = num;
        while (left <= right) {
            long mid = left + (right - left) / 2, t = mid * mid;
            if (t == num) return true;
            else if (t < num) left = mid + 1;
            else right = mid - 1;
        }
        return false;
    }
};

下面這種方法就是純數學解法了,利用到了這樣一條性質,完全平方數是一系列奇數之和,例如:

1 = 1
4 = 1 + 3
9 = 1 + 3 + 5
16 = 1 + 3 + 5 + 7
25 = 1 + 3 + 5 + 7 + 9
36 = 1 + 3 + 5 + 7 + 9 + 11
....
1+3+...+(2n-1) = (2n-1 + 1)n/2 = n*n

這裡就不做證明了,我也不會證明,知道了這條性質,就可以利用其來解題了,時間複雜度為O(sqrt(n))。

解法四:

class Solution {
public:
    bool isPerfectSquare(int num) {
        int i = 1;
        while (num > 0) {
            num -= i;
            i += 2;
        }
        return num == 0;
    }
};

下面這種方法是第一種方法的類似方法,更加精簡了,時間複雜度為O(lgn):

解法五:

class Solution {
public:
    bool isPerfectSquare(int num) {
        long x = num;
        while (x * x > num) {
            x = (x + num / x) / 2;
        }
        return x * x == num;
    }
};

這道題其實還有O(1)的解法,這你敢信?簡直太喪心病狂了,詳情請參見論壇上的這個帖子

類似題目:

參考資料: