Leetcode | 202 Happy Number

分析

在快乐数的题意上,通常情况下我们都会去顺着题目的意思去寻找最终结果是否为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));
    }
}

posted @ 2024-08-09 13:24  Neking  阅读(4)  评论(0编辑  收藏  举报