int digitSquareSum(int n) {
int sum = 0, tmp;
while (n) {
tmp = n % 10;
sum += tmp * tmp;
n /= 10;
}
return sum;
}
bool isHappy(int n) {
int slow, fast;
slow = fast = n;
do {
slow = digitSquareSum(slow);
fast = digitSquareSum(fast);
fast = digitSquareSum(fast);
} while(slow != fast);
if (slow == 1) return1;
elsereturn0;
}
for nin [1,10), g(n)>=n, since g(n)=n*n>=nwith equality hold onlyfor n=1
for other n with only highest digit nonzero (eg. 10, 90, 500, 4000,20000, etc), g(n)<n
and we can factor n into sum of numbers with only highest digitnonzero, eg. 12045 = 10000 + 2000 + 40 + 5
in this way, we can show for any n>=100, g(n) < n 对于任意正数n,跳转结果是有限的
环的大小
input: n (positive integer)
func g = digitSquareSum
while n>99
n = g(n)
output: HappyTable(n)
可以计算[1,100]里面的所有情况,从而得到环的大小,以及这100个数的对应是否是开心数的表。
使用表或者数组存储每步的计算结果和判断结果 The common choice is to use map or set to check if there is a loop. since the maximum sum is no greater than 2x2 + 9x9x9 (2,999,999,999), we can use a 1000 lengh hashtable . It's not O(1) space but it's faster than the fast-slow pointer solution.
class Solution {
public:
int tran(int n){
int ans = 0;
while(n){
ans += pow(n%10, 2);
n/=10;
}
return ans;
}
bool isHappy(int n) {
bool rep[1000];
memset(rep, 0, sizeof(rep));
n = tran(n);
while(!rep[n]){
rep[n] = true;
if(n == 1)
returntrue;
n = tran(n);
}
returnfalse;
}
};
publicboolean isHappy(int n) {
Set<Integer> inLoop = new HashSet<Integer>();
int squareSum,remain;
while (inLoop.add(n)) {
squareSum = 0;
while (n > 0) {
remain = n%10;
squareSum += remain*remain;
n /= 10;
}
if (squareSum == 1)
returntrue;
else
n = squareSum;
}
returnfalse;
}