LeetCode 367. Valid Perfect Square

問題連接

LeetCode 367. Valid Perfect Squarehtml

題目解析

判斷一個正數是不是徹底平方數,不可以使用sqrt函數。c++

解題思路

這是一道簡單題,可是卻挺有思考價值的。本題有不少種解法,思路各異,能夠都看看。算法

無數種解法

解法一

數學裏有一個概念叫作等差數列,徹底平方數剛好是奇數等差數列之和。1+3+5+...+(2n-1)=(1+2n-1)n/2=n^2。既然有了這個,那就好辦了,從小到大依次減去奇數,最後判斷是否等於0便可。時間複雜度爲 \(O(sqrt(n))\)。參考代碼以下:函數

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

解法二

從1搜索到sqrt(num),時間複雜度爲 \(O(sqrt(n))\)。參考代碼以下:spa

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

解法三

其實就是搜索一個數,天然能夠想到二分法。時間複雜度 \(O(lg(n))\)。參考代碼以下:code

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;
    }
};

解法四

萬惡的算法,居然還有一個 \(O(1)\) 的解法,不過很難弄懂。參考連接:O(1) time c++ solution inspired by Q_rsqrt。想弄懂的還能夠參考一下這個概念:Fast Inverse Square Roothtm

代碼大概是這個樣子的,學不來學不來:blog

class Solution {
public:
    bool isPerfectSquare(int num) {
        if (num < 0) return false;
        int root = floorSqrt(num);
        return root * root == num;
    }

    int32_t floorSqrt(int32_t x) {
        double y=x; int64_t i=0x5fe6eb50c7b537a9;
        y = *(double*)&(i = i-(*(int64_t*)&y)/2);
        y = y * (3 - x * y * y) * 0.5;
        y = y * (3 - x * y * y) * 0.5;
        i = x * y + 1; return i - (i * i > x);
    }
};

LeetCode All in One題解彙總(持續更新中...)ip

本文版權歸做者AlvinZH和博客園全部,歡迎轉載和商用,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利.leetcode

相關文章
相關標籤/搜索