LeetCode精選TOP面試題202.快樂數

題目描述

編寫一個算法來判斷一個數是不是“快樂數”。
題目來源:LeetCode
一個“快樂數”定義爲:對於一個正整數,每一次將該數替換爲它每個位置上的數字的平方和,然後重複這個過程直到這個數變爲 1,也可能是無限循環但始終變不到 1。如果可以變爲 1,那麼這個數就是快樂數。

示例: 
輸入: 19
輸出: true
解釋: 
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

解題思路

這是一個在編程的時候會出現死循環的問題,個人認爲重點工作其實倒不是怎麼判斷是不是快樂數,而是找到打破循環的方法或者條件。

  • 思路1 :快慢指針
    慢指針slower每次前進一步(進行一次平方計算),快指針faster每次前進兩步(進行兩次平方計算),當slower和faster不相等的時候,就一直循環。那爲啥還說能打破循環呢?
    這是因爲當快慢指針相等的時候會停止循環,相等的有兩種情況:
    • 當慢指針和快指針都通過計算變成了1;
    • 當慢指針走過一圈之後,快指針肯定恰好走過了兩圈,如果不是快樂數,快慢指針的值肯定是相同的;

之所以選擇快指針走兩步而不是三步四步,是因爲1,2公倍數最小,公約數最多,這樣最節省空間和時間

  • 思路2 :藉助HashSet
    哈希Set特點就是不允許重複,那隻要每次求和之後,判斷當前的值n是否已經存在於hashset中就好啦,存在就不是快樂數,直接return false,不存在就添加進hashset,直到n 變成1跳出循環,或者返回false。
  • 思路3 :投機取巧
    小於10的數中,只有1和7是快樂數,借鑑leetcode上大神的思路,所以,投機取巧就很簡單了:
    • 只要每次計算得到的n大於10,那麼就繼續計算;
    • 每次計算得到的n小於10,如果等於1或者7,就是快樂數,不等就不是。

代碼實現(Java)

/**
 * @author : flower48237
 * @2020/3/16 20:38
 * title : LeetCode精選TOP面試題202.快樂數
 */
public class Solution3 {
    public boolean isHappy(int n) {
    	// 法 1 -- 快慢指針
        int slower = n;
        int faster = n;
        do {
            slower = getSqrtSum(slower);
            faster = getSqrtSum(faster);
            faster = getSqrtSum(faster);
        }while (slower != faster);
        return slower == 1;// 返回slower和1是否相等的判定值
        
    	// 法 2 -- 藉助HashSet
        HashSet<Integer> hashset = new HashSet<Integer>();
        hashset.add(n);
        if (n == 1){
            return true;
        }
        while (n != 1){
            n = getSqrtSum(n);
            if (hashset.contains(n)){
                return false;
            }
            hashset.add(n);
        }
        return true;
        
        // 法 3 -- 投機取巧
        while (true){
            if (n < 10){
                if (n == 1 || n == 7) {
                    return true;
                }else {
                    return false;
                }
            }
            n = getSqrtSum(n);
        }
    }
    // 三個方法都會用到的計算平方的步驟
    public int getSqrtSum(int num){
        int sum = 0;
        while (num > 0){
            int item = num % 10;
            sum += item * item;
            num /= 10;
        }
        return sum;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章