202. 快乐数
- 思路分析
- 代码实现-Java
- 代码优化
思路分析
本人没有思路
在看题的时候,我不知道如果 不是快乐数怎么处理。我感觉是会死循环,一直加下去。没有考虑到会有重复数字出现。
为什么不会进行死循环?(为什么会有重复数字出现?)
详情请看力扣。
位数 | 目前的数字 | 下一个数字 |
---|---|---|
1 | 9 | 81 |
2 | 99 | 162 |
3 | 999 | 243 |
4 | 9999 | 324 |
10 | 9999999999 | 810 |
13 | 9999999999999 | 1053 |
2^31 = 2147483648
2^31-1 = 2147483647;
十位的9(9999999999)已经比2^31-1大了。按照题意 它的下一个数为810,810是三位。我们找到下一个为四位的数,也就是13个9。
对于 3 位数的数字,它的下一个不可能大于 243。这意味着它要么被困在 243以下的循环内,要么跌到 1。
4 位或 4 位以上的数字在每一步都会丢失一位,直到降到 3 位为止。
所以我们知道,最坏的情况下,算法可能会在 243 以下的所有数字上循环,然后回到它已经到过的一个循环或者回到 1。但它不会无限期地进行下去,所以排除无限循环的情况。
代码实现-Java
class Solution {
public boolean isHappy(int n) {
Set<Integer> myset = new HashSet<Integer>();
int num = n;
int sum= 0;
while(true) {
//求出这个和
sum = 0;
while(num != 0) {//这里不能写 while(num)
int tmp = num % 10;
sum += tmp*tmp;
num /= 10;
}
if(sum == 1) {return true;}
if(myset.contains(sum)) {
//无限循环
return false;
} else {
myset.add(sum);
}
num = sum;
}
}
}
代码优化
函数提取:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。这个功能会多次利用,因此应该提取出一个函数。这里用private就是同类中的函数才能访问。
private int getSum(int num) {
int sum= 0;
while(num != 0) { //这里不能写 while(num)
int tmp = num % 10;
sum += tmp*tmp;
num /= 10;
}
return sum;
}
while(true)和里面的 return true,false可以做调整。而且sum和n可以合并。
//摘自力扣
public boolean isHappy(int n) {
Set<Integer> seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getNext(n);
}
return n == 1;
}