202. Happy Number
Write an algorithm to determine if a number is "happy".
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
Example: 19 is a happy number
- 12 + 92 = 82
- 82 + 22 = 68
- 62 + 82 = 100
- 12 + 02 + 02 = 1
解題思路:直接根據題目所示步驟編程,重複計算平方和,得到一系列數字,當某個數重複出現時(可看成這些數組成的鏈 存在圈),則將無休止地繼續計算平方和,因此不是Happy Number。
錯誤範例:
class Solution {
private:
int squaredAdd(int num){
int sum = 0, digit;
while(num){
digit = num % 10;
sum += digit * digit;
num /= 10;
}
return sum;
}
public:
bool isHappy(int n) {
int number = n;
while(1){
number = squaredAdd(number);
if(number == 1) return true;
if(number == n) return false; //此處錯誤!
}
}
};
錯誤原因:數鏈存在圈,但交匯點不一定在數字n處(不一定在n處開始進入圈)。以n=2爲例,重複計算平方和得到數鏈:2,4,16,37,58,89,145,42,20,4,16... 將數鏈寫成環形可發現在數字4進入圈,而不是2,所以此方法錯誤。
正確方法:可參考檢測鏈表中是否有圈的方法,使用兩個指針,快指針和慢指針。快指針每次走兩步,慢指針每次走一步,若存在圈,則快指針會追上慢指針,二者終將相等。
class Solution {
private:
int squaredAdd(int num){
int sum = 0, digit;
while(num){
digit = num % 10;
sum += digit * digit;
num /= 10;
}
return sum;
}
public:
bool isHappy(int n) {
int slow = n, fast = n;
while(1){
slow = squaredAdd(slow);
fast = squaredAdd(fast);
fast = squaredAdd(fast);
if(fast == 1) return true; //必須先判斷fast是否等於1,否則會出錯
if(fast == slow) return false; //eg. n爲1時應返回true,若先判斷fast是否等於slow,則會返回false,錯誤!
}
}
};