[LeetCode] Sum of Square Numbers 平方數之和
阿新 • • 發佈:2018-12-27
Given a non-negative integer c
, your task is to decide whether there're two integers a
and b
such that a2 + b2 = c.
Example 1:
Input: 5 Output: True Explanation: 1 * 1 + 2 * 2 = 5
Example 2:
Input: 3 Output: False
這道題讓我們求一個數是否能由平方數之和組成,剛開始博主沒仔細看題,沒有看到必須要是兩個平方數之和,博主以為任意一個就可以。所以寫了個帶優化的遞迴解法,樓主已經不是上來就無腦暴力破解的辣個青蔥騷年了,直接帶優化。可是居然對14返回false,難道14不等於1+4+9嗎,結果仔細一看,必須要兩個平方數之和。好吧,那麼遞迴都省了,直接判斷兩次就行了。我們可以從c的平方根,注意即使c不是平方數,也會返回一個整型數。然後我們判斷如果i*i等於c,說明c就是個平方數,只要再湊個0,就是兩個平方數之和,返回true;如果不等於的話,那麼算出差值c - i*i,如果這個差值也是平方數的話,返回true。遍歷結束後返回false,參見程式碼如下:
解法一:
class Solution { public: bool judgeSquareSum(int c) { for (int i = sqrt(c); i >= 0; --i) { if (i * i == c) return true; int d = c - i * i, t = sqrt(d); if (t * t == d) return true; } return false; } };
下面這種方法用到了集合set,從0遍歷到c的平方根,對於每個i*i,都加入集合set中,然後計算c - i*i,如果這個差值也在集合set中,返回true,遍歷結束返回false,參見程式碼如下:
解法二:
class Solution { public: bool judgeSquareSum(int c) { unordered_set<int> s; for (int i = 0; i <= sqrt(c); ++i) { s.insert(i * i); if (s.count(c - i * i)) return true; } return false; } };
上面兩種方法都不是很高效,來看下面這種高效的解法。論壇上有人稱之為二分解法,但是博主怎麼覺得不是呢,雖然樣子很像,但是並沒有折半的操作啊。這裡用a和b代表了左右兩個範圍,分別為0和c的平方根,然後while迴圈遍歷,如果a*a + b*b剛好等於c,那麼返回true;如果小於c,則a增大1;反之如果大於c,則b自減1,參見程式碼如下:
解法三:
class Solution { public: bool judgeSquareSum(int c) { int a = 0, b = sqrt(c); while (a <= b) { if (a * a + b * b == c) return true; else if (a * a + b * b < c) ++a; else --b; } return false; } };
類似題目:
參考資料: