[LeetCode刷題筆記] 202 – Happy Number

題目描述:

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