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,错误!
}
}
};