題目描述:
Write an algorithm to determine if a number n
is happy.
A happy number is a number defined by the following process:
Starting with any positive integer, replace the number by the sum of the squares of its digits.
Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.
Those numbers for which this process ends in 1 are happy.
Return true
if n
is a happy number, and false
if not.
Example 1:
Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
Example 2:
Input: n = 2
Output: false
Constraints:
1 <= n <= 231 - 1
一刷題解(HashSet):
這一題需要我們去判斷一個數是否為快樂數。根據維基百科的描述,快樂數的意思是:在給定的進位制下,該數字所有數位的平方和,得到的新數再次求所有數位的平方和,如此重複進行,最終結果必為1。其實就正如題目描述的證明過程一樣:
- 自任意正整數開始,將其中的每一位的數字平方後相加,再把這個和取代原來的正整數,繼續進行計算。
- 重複這個每個數位平方後相加的步驟,直到得出的和等於1,則這個數是一個「快樂數」。
- 如果這個數無法得出1,一直循環,並重複得出到之前得出過的結果,那這個數就不是「快樂數」。
理清思路後,整個邏輯就很簡單了。首先我們要有一個HashSet去記錄計算過程中的和,然後只要n != 1,就一直循環,直到n == 1(快樂),或者n等於hashSet裡的元素(重複了就不快樂)之後終止循環。
而位數的計算則通過重複的求模完成。把一個數(n)進行 % 10可以得到當前數的個位數,把這個個位數平方後加到本輪計算的暫存值中,然後再將n /= 10,整個計算是一個把指標從個位數一直往前推的過程。
比如n = 365,暫存值為curr(初如為0)
- 365 % 10 = 5, curr = 5^2 + 0, 365 / 10 = 36
- 36 % 10 = 6, curr = 6^2 + 5^2, 36 / 10 = 3
- 3 % 10 = 3, curr = 3^2 + 6^2 + 5^2, 3 / 10 = 0 => break;
public class Solution {
public bool IsHappy(int n) {
if(n == 1) { return true; }
//記錄計算結果的HashSet
HashSet<int> hash = new HashSet<int>();
//只要n!=1,就一直重複
while(n != 1)
{
//本輪計算的暫存值
var curr = 0;
//得到每個數位的平方並相加到暫存值中
while(n > 0)
{
var remainder = n % 10;
curr = remainder * remainder + curr;
n /= 10;
}
//如果是之前曾得到過的結果,代表這不是一個快樂數,返回false
if(hash.Contains(curr)) { return false; }
//記錄計算結果
hash.Add(curr);
//將暫存值取代原來的數
n = curr;
}
return true;
}
}