2種解法 - 判斷快樂數


題目

編寫一個算法來判斷一個數是不是“快樂數”。

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

示例:

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


解法一(循環)

思路:每次計算結果存儲起來,如果集合中再次發現了這個值,表示出現循環不適快樂數,如果計算到1了還沒出現相同的值,表示是快樂數

  1. 最外層循環判斷是否是1,如果是1則退出循環,認爲是快樂數
  2. 內層循環進行計算,如果沒重複將結果存儲起來
  3. 如果發現有值重複,則不是快樂數,提前返回
  • 時間複雜度是空間複雜度的ln(n)ln(n)倍,具體空間複雜度不太好表達,如果很大的一個是可能導致空間溢出。
public class Solution {
    public bool IsHappy(int n) {
        List<int> r = new List<int>();
        int m = 0;
        while(n>1)
        {
            m = 0;
            r.Add(n);
            while(n>0)
            {
                m += (int)Math.Pow(n%10,2);
                n/=10;
            }
            n = m;
            if(r.Contains(n))
            {
                return false;
            }
        }
        return true;
    }
}

解法二(快慢指針)

思路:使用快慢指針思想,如果是快樂數那麼最後結果將保持爲1,如果是循環那麼當兩指針相遇時即爲循環點。即,同一段距離速度是2倍,時間相同,第一次相遇就是循環的起點,s0=v0t0s1=2v0t0s_0=v_0t_0,s_1=2v_0t_0

  1. 按規則對數值進行計算
  2. 進行快慢指針推進
  3. 循環結束後判斷快樂數
  • 時間複雜度是解法一的3倍
  • 空間複雜度:O(1)
public class Solution {
    public int getValue(int n)
    {
        int m = 0;
        while(n>0)
        {
            m += (int)Math.Pow(n%10,2);
            n/=10;
        }
        return m;
    }
    public bool IsHappy(int n) {
        int m = n;
        do
        {
            m = getValue(m);//慢指針m走1步
            n = getValue(n);
            n = getValue(n);//快指針n走2步
        }while(m != n);
        return m==1;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章