202. 快樂(lè)數(shù)
題目
編寫(xiě)一個(gè)算法來(lái)判斷一個(gè)數(shù) n 是不是快樂(lè)數(shù)。
「快樂(lè)數(shù)」定義為:對(duì)于一個(gè)正整數(shù),每一次將該數(shù)替換為它每個(gè)位置上的數(shù)字的平方和舞终,然后重復(fù)這個(gè)過(guò)程直到這個(gè)數(shù)變?yōu)?1废膘,也可能是 無(wú)限循環(huán) 但始終變不到 1。如果 可以變?yōu)? 1般又,那么這個(gè)數(shù)就是快樂(lè)數(shù)彼绷。
如果 n 是快樂(lè)數(shù)就返回 True ;不是茴迁,則返回 False 寄悯。
示例:
輸入:19
輸出:true
解釋?zhuān)?12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
思路
通過(guò)反復(fù)調(diào)用 getNext(n) 得到的鏈?zhǔn)且粋€(gè)隱式的鏈表。隱式意味著我們沒(méi)有實(shí)際的鏈表節(jié)點(diǎn)和指針堕义,但數(shù)據(jù)仍然形成鏈表結(jié)構(gòu)猜旬。起始數(shù)字是鏈表的頭 “節(jié)點(diǎn)”,鏈中的所有其他數(shù)字都是節(jié)點(diǎn)倦卖。next 指針是通過(guò)調(diào)用 getNext(n) 函數(shù)獲得昔馋。
意識(shí)到我們實(shí)際有個(gè)鏈表,那么這個(gè)問(wèn)題就可以轉(zhuǎn)換為檢測(cè)一個(gè)鏈表是否有環(huán)糖耸。因此我們?cè)谶@里可以使用弗洛伊德循環(huán)查找算法秘遏。這個(gè)算法是兩個(gè)奔跑選手,一個(gè)跑的快嘉竟,一個(gè)跑得慢邦危。在龜兔賽跑的寓言中,跑的快的稱(chēng)為 “烏龜”舍扰,跑得快的稱(chēng)為 “兔子”倦蚪。
不管烏龜和兔子在循環(huán)中從哪里開(kāi)始,它們最終都會(huì)相遇边苹。這是因?yàn)橥米用孔咭徊骄拖驗(yàn)觚斂拷粋€(gè)節(jié)點(diǎn)(在它們的移動(dòng)方向上)陵且。
代碼
class Solution {
public boolean isHappy(int n) {
int slowPoint = n;
int fastPoint = getNext(n);
while( fastPoint != 1 && slowPoint != fastPoint){
slowPoint = getNext(slowPoint);
fastPoint = getNext(getNext(fastPoint));
}
return fastPoint == 1;
}
public int getNext(int n){
int total = 0;
while(n > 0){
int d = n % 10;
n /= 10;
total += d * d;
}
return total;
}
}