題目
編寫一個算法來判斷一個數是不是“快樂數”。
一個“快樂數”定義爲:對於一個正整數,每一次將該數替換爲它每個位置上的數字的平方和,然後重複這個過程直到這個數變爲 1,也可能是無限循環但始終變不到 1。如果可以變爲 1,那麼這個數就是快樂數。
示例:
輸入: 19
輸出: true
解釋:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
解法一(循環)
思路:每次計算結果存儲起來,如果集合中再次發現了這個值,表示出現循環不適快樂數,如果計算到1了還沒出現相同的值,表示是快樂數
- 最外層循環判斷是否是1,如果是1則退出循環,認爲是快樂數
- 內層循環進行計算,如果沒重複將結果存儲起來
- 如果發現有值重複,則不是快樂數,提前返回
- 時間複雜度是空間複雜度的倍,具體空間複雜度不太好表達,如果很大的一個是可能導致空間溢出。
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倍,時間相同,第一次相遇就是循環的起點,
- 按規則對數值進行計算
- 進行快慢指針推進
- 循環結束後判斷快樂數
- 時間複雜度是解法一的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;
}
}