Leetcode 202 快乐数 与 链表查环
对一个正整数循环,取各数位上的值的平方的和,这个和的值作为下一次循环的输入。
如果这个和在某一次变成1,返回true (为快乐数)
如果这个和永远不会变成1,返回false (不是快乐数)
看到这道题第一想法就是暴力解,但是明显有更好的方法,并且也没有办法可以判断出这个“和”是不是永远变成1 (while loop 永远不会结束?)
所以,要猜测题中是不是有隐藏终止条件:
随着loop 越来越多,我们可以猜测n的增长趋势
- 持续增加,永远不会变成1
- 在某个环中循环,永远不会变成1 (包括0的情况)
- 会变成1
对于9999来说,下一次循环会落在81*4 中,
对于999999来说,下一次循环一定比当前数小。
所以不会持续增加。
那么就就是判断在计算每次循环的和的值,存不存在环。
第一种方法,存一个set,记录所有被访问过的节点。
第二种方法,双指针,一个比另外一个快一倍。
先贴第一种方法:
class Solution {
public boolean isHappy(int n) {
Set<Integer> hash_set = new HashSet<>();
while(true){
hash_set.add(n);
n = getNext(n);
if (n==1){
return true;
}
if (hash_set.contains(n)){
return false;
}
}
}
private int getNext(int n){
int sum = 0;
while (n!=0){
int cur = n%10;
n = n/10;
sum += cur*cur;
}
return sum;
}
}
第二种方法
class Solution {
public boolean isHappy(int n) {
int slow = n, fast = n;
do{
slow = getNext(slow);
fast = getNext(getNext(fast));
}while(slow!=fast);
return slow == 1;
}
private int getNext(int n){
int sum = 0;
while (n!=0){
int cur = n%10;
n = n/10;
sum += cur*cur;
}
return sum;
}
}
如果链表有环,slow和fast会相遇,如果此时相遇在1,说明会达到1。