題目在問什麼
給一個正整數 n,不斷把它替換成「各位數字平方和」。
如果最後會走到 1,它就是 happy number;如果會卡進不包含 1 的循環,就不是。
例子
Input: n = 19
Output: true
因為:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
解題思路
這題關鍵不是怎麼算平方和,而是怎麼判斷自己是否已經進入循環。
最直接的做法是用 HashSet<int> 記錄每一輪算出來的結果:
- 如果某次結果變成
1,就回傳true - 如果某次結果之前已經出現過,代表進入循環,回傳
false
如何拆出每一位數
每輪計算平方和時,可以反覆做:
n % 10取得個位數n /= 10去掉個位數
把每一位的平方累加起來,就是下一輪的新數字。
代碼
public class Solution
{
public bool IsHappy(int n)
{
if (n == 1) { return true; }
HashSet<int> hash = new HashSet<int>();
while (n != 1)
{
int curr = 0;
while (n > 0)
{
int remainder = n % 10;
curr = remainder * remainder + curr;
n /= 10;
}
if (hash.Contains(curr)) { return false; }
hash.Add(curr);
n = curr;
}
return true;
}
}
複雜度
這題實際上狀態數量不會太大,因此可以視為很小的循環空間。
- 時間複雜度:
O(log n)到收斂,每輪要拆各位數 - 空間複雜度:
O(log n)或可視作有限狀態集合
這題先記住的重點
- 這題真正要處理的是「循環檢測」
HashSet是最直觀的做法- 拆數字位數時,
% 10和/ 10是標準手法