Leetcode 202 快樂數(最詳細講解)

2021-10-03 18:07:45 字數 2817 閱讀 6770

algorithm

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

示例:輸入: 19

輸出: true

解釋:12+

92=82

1^2 + 9^2 = 82

12+92=

828 2+

22=68

8^2 + 2^2 = 68

82+22=

686 2+

82=100

6^2 + 8^2 = 100

62+82=

10012+

02+0

2=11^2 + 0^2 + 0^2 = 1

12+02+

02=1

思路1:

這道題定義了一種快樂數,就是說對於某乙個正整數,如果對其各個位上的數字分別平方,然後再加起來得到乙個新的數字,再進行同樣的操作,如果最終結果變成了1,則說明是快樂數,如果一直迴圈但不是1的話,就不是快樂數,那麼現在任意給我們乙個正整數,讓我們判斷這個數是不是快樂數,題目中給的例子19是快樂數,那麼我們來看乙個不是快樂數的情況,比如數字11有如下的計算過程:

1^2 + 1^2 = 2

2^2 = 4

4^2 = 16

1^2 + 6^2 = 37

3^2 + 7^2 = 58

5^2 + 8^2 = 89

8^2 + 9^2 = 145

1^2 + 4^2 + 5^2 = 42

4^2 + 2^2 = 20

2^2 + 0^2 = 4

我們發現在算到最後時數字4又出現了,那麼之後的數字又都會重複之前的順序,這個迴圈中不包含1,那麼數字11不是乙個快樂數,發現了規律後就要考慮怎麼用**來實現,我們可以用 hashset 來記錄所有出現過的數字,然後每出現乙個新數字,在 hashset 中查詢看是否存在,若不存在則加入表中,若存在則跳出迴圈,並且判斷此數是否為1,若為1返回true,不為1返回false,**如下:

class solution 

n = sum;

if(st.

count

(n))

break

; st.

insert

(n);

}return n ==1;}};

思路二:這個單鏈表快慢指標講很多了,可以直接跳過,去看看演算法規模分析吧!

泛化鍊錶結構:如果我們 把鍊錶的節點看成問題中的狀態 的話,它可以代表問題中的乙個數字、乙個階段等等,是很泛化的東西。而鍊錶的唯一指向關係它又代表什麼呢?它其實代表著 狀態與狀態之間是唯一確定轉換 的。也就是說從當前狀態是唯一確定轉換到下乙個狀態的。顯然快樂數的轉換規則完美的符合了這個特性。

我們根據題目的意思就將 1 作為鍊錶的結尾即 null。

那麼在單鏈表中一直走不到空位址意味著什麼?就意味著鍊錶有環唄。那麼這個快樂數問題就被抽象為鍊錶中是否有環的問題。即,如果這個鍊錶有環那麼就不是快樂數,如果鍊錶沒環,能指到空位址 1 的話那就說明這個數就是快樂數。

從上面我們得到了解決這個問題的演算法思維,但是會不會出現這個鍊錶太長了,有上個幾千、幾萬、幾十萬的鍊錶單元,影響我們找不到結果呢?我們來考慮一下這個演算法的規模。

首先,如果輸入值為 int,那麼能知道 int 最多也就是乙個以 2 開頭的 10 位的數字。接著我們來考慮這樣乙個問題,在 int 資料範圍中,哪乙個數字 n 它所對應的下乙個數字 n 是最大的?

我們能構造得到 1 999 999 999,那麼只有構造出 1 個 1 ,9 個 9 的數字在 int 範圍內就是最大的,那麼下乙個節點時多少呢?根據快樂數的定義能得到 9^2 \times9 + 1 = 7309

2×9+1=730,那麼 730 就是在整形範圍之內任何乙個數字所能對映到的下乙個數字都不會超過 730,也就意味著當前所抽象出來的鍊錶結構中節點數目最多不會超過 730 個,如果快指標一次走兩步、慢指標一次走一步的話,那麼慢指標走的最多,也只不過走了 731\times2 = 1462731×2=1462 步,而快指標就是走了 731731 步。

所以至此就證明完了,在整形快樂數中進行單鏈表判環的操作的話,操作步驟是有限的,就取個整吧,最多最多也就 2000 步了。所以這個方案是高效可行的。

使用「快慢指標」思想找出迴圈:「快指標」每次走兩步,「慢指標」每次走一步,當二者相等時,即為乙個迴圈週期。此時,判斷是不是因為1引起的迴圈,是的話就是快樂數,否則不是快樂數。

注意:此題不建議用集合記錄每次的計算結果來判斷是否進入迴圈,因為這個集合可能大到無法儲存;另外,也不建議使用遞迴,同理,如果遞迴層次較深,會直接導致呼叫棧崩潰。不要因為這個題目給出的整數是int型而投機取巧。

就像跑步一樣,快樂數跑的是100m衝刺,非快樂數則是在1個400公尺的環形跑道裡無休止的跑下去。

快慢指標就像是專業運動員和業務運動員,在100m的跑道上,兩個都會跑到1. 而在環形跑道上,兩個指標雖然見面了,但是估計慢指標才跑完一圈,快指標已經跑完兩圈了

class

solution

return slow ==1;

}int

findnext

(int n)

return res;}}

;

題解 LeetCode 202 快樂數

編寫乙個演算法來判斷乙個數n是不是快樂數。快樂數 定義為 對於乙個正整數,每一次將該數替換為它每個位置上的數字的平方和,然後重複這個過程直到這個數變為 1,也可能是無限迴圈但始終變不到 1。如果可以變為1,那麼這個數就是快樂數。如果n是快樂數就返回true 不是,則返回false。輸入 19 輸出 ...

小白學習 leetcode 之202快樂數

編寫乙個演算法來判斷乙個數 n 是不是快樂數。快樂數 定義為 對於乙個正整數,每一次將該數替換為它每個位置上的數字的平方和,然後重複這個過程直到這個數變為 1,也可能是 無限迴圈 但始終變不到 1。如果 可以變為 1,那麼這個數就是快樂數。如果 n 是快樂數就返回 true 不是,則返回 false...

雜湊 簡單 202 快樂數

題目 編寫乙個演算法來判斷乙個數 n 是不是快樂數。快樂數 定義為 對於乙個正整數,每一次將該數替換為它每個位置上的數字的平方和。然後重複這個過程直到這個數變為 1,也可能是 無限迴圈 但始終變不到 1。如果 可以變為 1,那麼這個數就是快樂數。如果 n 是快樂數就返回 true 不是,則返回 fa...