思路
题目中提示说对于一个正整数,要么最终到达1,要么进入无限循环。也就是说,在求平方和时出现了以前出现过的数字就表示进入了循环,也即该数不是快乐数。
那么问题就转化为检查一个数字是否重复出现,我首先想到的就是将出现过的数字都放在集合里,后面每次求和都检验其是否出现过。
在题解中看到了解决这种问题的第二种常规思路:快慢指针。由于每次求和的行为都可以看做链表的延伸,那么检查有无重复数字也就是检查链表有没有环,这就无可厚非地要用到快慢指针法了。
代码
解法一:哈希集合法
class Solution {
public:
bool isHappy(int n) {
// 存储出现过的数字的哈希集合
unordered_set<int> s;
// 当没有出现过时
while (!s.count(n)) {
s.insert(n);
int sum = 0;
while (n > 0) {
sum += pow(n % 10, 2);
n /= 10;
}
if (sum == 1)
return true;
n = sum;
}
// 遇到了出现过的数字
return false;
}
};
解法二:快慢指针法
// 执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗:5.9 MB, 在所有 C++ 提交中击败了73.70%的用户
class Solution {
public:
int getNext(int n) {
int next = 0;
while (n > 0) {
next += pow(n % 10, 2);
n /= 10;
}
return next;
}
bool isHappy(int n) {
int slow = n, fast = n;
do {
slow = getNext(slow);
fast = getNext(getNext(fast));
if (fast == 1)
return true;
} while (slow != fast);
return false;
}
};