分析
在快乐数的题意上,通常情况下我们都会去顺着题目的意思去寻找最终结果是否为1,而后面的另一句话很有启示意义:"也可能是无限循环,但始终变不到1",那么为什么不会是无限不循环呢?
证明
- 范围限制:对于一个(d)位数的正整数(n),其最大值为 99d =Max
- 位数减少:每次计算之后,数字位数d要么减少,要么保持不变,范围限制提供了一个位数的最大边界
- 有限状态空间:在Max这个数字范围限制下,即便所得的结果,将这个空间里面的所有元素全部遍历一遍,想陷入无限不循环则是不可能的,一定会出现重复计算过的数字,从而进行无限循环之中
从上面的证明,我们可以分析得出,在有限的状态空间,只有1的平方进入无限循环,自己乘自己还是自己,其它的数会在这个有限空间里面收缩,计算结果要么为1,要么就会在这个空间里不停重复,重复检测最好的方式刚好是哈希表,产生了哈希冲突就代表有重复值出现,与检测链表中是否存在环结构,不谋而合。
循环检测
:快乐数的检测过程实际上是一个寻找循环的过程,无论是1自身的循环,还是在有限空间内的循环。这种思想可以应用于检测链表中的循环、图中的环路等问题
哈希表
:使用哈希表来存储已经计算过的值,可以避免重复计算,提高效率。在实际应用中,哈希表常用于缓存、去重、快速查找等场景
取余运算和利用余数作为循环条件这个小技巧挺精致
主类
package com.github.dolphinmind.hash;
import java.util.HashSet;
import java.util.Set;
/**
* @author dolphinmind
* @ClassName HappyNumber
* @description
* @date 2024/8/9
*/
public class HappyNumber {
public boolean isHappy(int n ) {
Set<Integer> seen = new HashSet<>();
/**
* n == 1 是快乐数的判断标准
* seen.contains(n) 是判断是否出现过n,即判断是否进入了循环
*/
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getSquareSum(n);
}
return n == 1;
}
private int getSquareSum(int n) {
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
}
测试类
package com.github.dolphinmind.hashcode;
import com.github.dolphinmind.hash.HappyNumber;
import org.junit.Test;
/**
* @author dolphinmind
* @ClassName HappyNumberTest
* @description
* @date 2024/8/9
*/
public class HappyNumberTest {
@Test
public void test_IsHappy() {
System.out.println(new HappyNumber().isHappy(19));
}
}
标签:202,dolphinmind,int,Number,public,循环,哈希,import,Leetcode
From: https://www.cnblogs.com/dolphinmind/p/18350600