方法一:哈希表检测循环
利用HashSet来记录平方和的结果,从关键字无限循环,可以得出, 重复过程中,要么变为1,要么无限循环;
class Solution {
public boolean isHappy(int n) {
HashSet<Integer> set = new HashSet<>();
// 重点:重复过程中,要么变为1,要么无限循环
while (true) {
n = getN(n);
if (n == 1) {
return true;
}
if (set.contains(n)) {
return false;
} else {
set.add(n);
}
}
// while (n != 1 && !set.contains(n)) {
// set.add(n);
// n = getN(n);
// }
// return n == 1;
}
public int getN(int n) {
int sum = 0;
while (n > 0) {
sum += Math.pow(n % 10, 2);
n /= 10;
}
return sum;
}
}
复杂度分析:这次的复杂度计算较为费解,可以看一下官方解析
- 时间复杂度:O(logn)
- 空间复杂度:O(logn)
方法二:快慢指针
若在重复平方和中没有得到1,则会在重复中形成环状循环,我们可以通过快慢指针来检测循环,若快指针追上了慢指针,则存在循环,返回false;
class Solution {
public boolean isHappy(int n) {
int slow = n;
int fast = getN(n);
while ((fast != 1 || slow != 1) && fast != slow) {
slow = getN(slow);
fast = getN(getN(fast));
}
if (fast == 1 || slow == 1) {
return true;
} else {
return false;
}
}
public int getN(int n) {
int sum = 0;
while (n > 0) {
sum += Math.pow(n % 10, 2);
n /= 10;
}
return sum;
}
}
复杂度分析:
- 时间复杂度:O(logn)
- 空间复杂度:O(1)