题目描述
解法:快慢指针
- 不建议用集合记录每次的计算结果来判断是否进入循环,因为这个集合可能大到无法存储;另外,也不建议使用递归,同理,如果递归层次较深,会直接导致调用栈崩溃
- 每个数字都会根据 各位平方和 指向另一个数字,所以从任意数字开始进行 各位平方和 的迭代操作,就相当于在链表上游走。如果 无限循环 但始终变不到 1,那说明肯定是链表游走到了环。
- 所以问题就转化成了快慢指针链表判环问题
class Solution {
public:
int getNext(int n)
{
int sum = 0;
while(n > 0)
{
int d = n % 10;
sum += d * d;
n /= 10;
}
return sum;
}
bool isHappy(int n) {
if(n == 1) return true;
int slow = n, fast = getNext(n);
while(slow != 1 && fast != 1 && slow != fast)
{
slow = getNext(slow);
fast = getNext(getNext(fast));
}
return slow == 1 || fast == 1;
}
};
在快慢指针的 while 循环判断问题上,有两种思路。
- 一种是上述,把 slow 初始化为 n,而 fast 初始化时要往后走一步,这样 while 判断里就可以写 slow != fast 时循环,这可以理解为 slow 和 fast 一开始都在 n 的往前一步的位置上,然后都走一下, slow 到 n,fast 到 n 的下一步。
- 另一种是 slow 和 fast 都初始化为 n,那么就不能用 while 了,而是 do while
int slow = n, fast = n;
do{
slow = getNext(slow);
fast = getNext(getNext(fast));
}while(slow != fast);