- 链接 : 快乐数
- 题意 :
- 思路:
(1)只要把数位平方和相加,判断是否等于1即可。循环判断则用set即可。
代码:
class Solution {
int check(int n){
int ans = 0;
while(n){
int tmp = n % 10;
ans += pow(tmp,2);
n /= 10;
}
return ans;
}
public:
bool isHappy(int n) {
bool ans = false;
set<int> vis;
vis.insert(n);
while(true){
int tmp = check(n);
if(tmp == 1){
ans = true;
break;
}
if(vis.count(tmp)){
break;
}
vis.insert(tmp);
n = tmp;
}
return ans;
}
};
(2)Floyd判圈方法。
刚开始没想到,后来看了官方题解,想到这个方法,在刘汝佳大神的蓝书里面有讲到。 P44,UVa11594这道题。
简单来说,a和b在一条直线上跑步,b的速度是a的二倍。如果这条直线后面是一个环,那么b肯定能追上a。
所以可以设tmp1 = check(tmp1), tmp2 = check(check(tmp2))。如果tmp2 == tmp1,那么就有环咯。
class Solution {
int check(int n){
int ans = 0;
while(n){
int tmp = n % 10;
ans += pow(tmp,2);
n /= 10;
}
return ans;
}
public:
bool isHappy(int n) {
bool ans = false;
int tmp1 = n, tmp2 = check(n);
while(true){
tmp1 = check(tmp1);
tmp2 = check(check(tmp2));
if(tmp1 == 1){
ans = true;
break;
}
if(tmp1 == tmp2){
break;
}
}
return ans;
}
};
本题很简单,但是考虑到有Floyd判圈这个省内存空间的好办法,就有研究的价值了。
- 遇到的问题:
最开始我赋值 tmp1 = n, tmp2 = check(tmp1),但是这样根本不是以二倍的速度。
蓝书上的初始化是 tmp1 = tmp2 = n, 然后 tmp1 check一次,tmp2连续check 2次。不过官方题解 初始化 tmp1 = n , tmp2 = check(n),这样对,并且更快。