题目解析:
只存在两种情况,一种情况是经过题目的运算后,最终结果变为1.另一种情况是经过题目运算后一直循环,即示例2的情况。
而两种情况其实可以归并为1种情况,将他们都看作在最后形成一个环,对于第一种情况,环上的数都是1,第二种则不是。此时我们只要判断成环的那个点的值是否为1就行。因为如果成环的那个点不是1,以后也不可能是1.
算法原理:
使用双指针。
这个双指针并不是一定要像链表那样有指向的,双指针是一种思想。就像可以把数组的下标当作指针一样,在这题中,可以把数字当作指针。而进行一次运算就相当于指针向下一位移动。
定义双指针,一个慢指针一个快指针
慢指针每次走一步,也就是每次循环中只运算一次。而快指针走两步,即运算两次。
当快指针和慢指针相等的时候,也就是他们相遇的时候。(注意,相遇的点不一定是环的入口点,可能在环的某个位置)
此时判断此点是否为1。
为什么这时判断就能决定是否为快乐数?从我们刚刚的题目解析可以知道,最终结果为1的快乐数,可以看作是环上的点都是1。而不是快乐数的相遇点不是1,首先,既然能相遇,那么说明他们一定在环里,那么既然在环里,如果是快乐数,那环内的值就应该都是1,所以当相遇点非1的时候,这个数就不是快乐数。
也就是说,在第二种非快乐数的情况下,快慢指针相等这个条件是用来标示他们已经在环中了。
代码编译:
C语言代码
int BitSquareSum(int n)
{
int ret = 0;
while(n)
{
ret += pow(n%10,2);
n/=10;
}
return ret;
}
bool isHappy(int n) {
//将数的运算当成指针的移动,将数看作指针
int slow = BitSquareSum(n) ,fast = BitSquareSum(BitSquareSum(n));
//判断相遇点是否为1
while(fast != slow)
{
slow = BitSquareSum(slow);
fast = BitSquareSum(BitSquareSum(fast));
}
return slow == 1;
}
C++代码
class Solution {
public:
int bitSquareSum(int n) {
int sum = 0;
while(n > 0)
{
int bit = n % 10;
sum += bit * bit;
n = n / 10;
}
return sum;
}
bool isHappy(int n) {
int slow = n, fast = bitSquareSum(n);
while(slow != fast)
{
slow = bitSquareSum(slow);
fast = bitSquareSum(bitSquareSum(fast));
}
return slow == 1;
}
};