哈希——202. 快乐数

简介: 本专栏按照数组—链表—哈希—字符串—栈与队列—二叉树—回溯—贪心—动态规划—单调栈的顺序刷题,采用代码随想录所给的刷题顺序,一个正确的刷题顺序对算法学习是非常重要的,希望对大家有帮助

1 题目描述

  1. 快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

2 题目示例

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:
输入:n = 2
输出:false

3 题目提示

1 <= n <= 231 - 1

4 思路

方法一:用哈希集合检测循环
我们可以先举几个例子。我们从7开始。则下一个数字是49(因为= 49),然后下一个数字是97(因为42+92= 97)。我们可以不断重复该的过程,直到我们得到1。因为我们得到了1,我们知道7是一个快乐数,函数应该返回true 。
再举—个例子,让我们从116开始。通过反复通过平方和计算下一个数字,我们最终得到58,再继续计算之后,我们又回到58。由于我们回到了一个已经计算过的数字,可以知道有一个循环,因此不可能达到1。所以对于116,函数应该返回false 。
根据我们的探索,我们猜测会有以下三种可能。

  1. 最终会得到1。
  2. 最终会进入循环。
  3. 值会越来越大,最后接近无穷大。

第三个情况比较难以检测和处理。我们怎么知道它会继续变大,而不是最终得到1呢?我们可以仔细想—想,每—位数的最大数字的下一位数是多少。
对于3位数的数字,它不可能大于243。这意味着它要么被困在243以下的循环内,要么跌到1。4位或4位以上的数字在每一步都会丢失一位,直到降到3位为止。所以我们知道,最坏的情况下,算法可能会在243以下的所有数字上循环,然后回到它已经到过的一个循环或者回到1。但它不会无限期地进行下去,所以我们排除第三种选择。
即使在代码中你不需要处理第三种情况,你仍然需要理解为什么它永远不会发生,这样你就可以证明为什么你不处理它。

算法分为两部分,我们需要设计和编写代码。

  1. 给一个数字n,它的下一个数字是什么?
  2. 按照—系列的数字来判断我们是否进入了一个循环。

第1部分我们按照题目的要求做数位分离,求平方和。
第⒉部分可以使用哈希集合完成。每次生成链中的下一个数字时,我们都会检查它是否已经在哈希集合中。
如果它不在哈希集合中,我们应该添加它。
如果它在哈希集合中,这意味着我们处于一个循环中,因此应该返回false 。
我们使用哈希集合而不是向量、列表或数组的原因是因为我们反复检查其中是否存在某数字。检查数字是否在哈希集合中需要O(1)的时间,而对于其他数据结构,则需要O(n)的时间。选择正确的数据结构是解决这些问题的关键部分。

方法二:数学
前两种方法是你在面试中应该想到的。第三种方法不是你在面试中会写的,而是针对对数学好奇的人,因为它很有趣。
下一个值可能比自己大的最大数字是什么?根据我们之前的分析,我们知道它必须低于243。因此,我们知道任何循环都必须包含小于243的数字,用这么小的数字,编写一个能找到所有周期的强力程序并不困难。
如果这样做,您会发现只有一个循环:4→16→3758→89 >145—> 42→〉20 →> 4。所有其他数字都在进入这个循环的链上,或者在进入1的链上。
因此,我们可以硬编码一个包含这些数字的散列集,如果我们达到其中一个数字,那么我们就知道在循环中。

5 我的答案

方法一:用哈希集合检测循环

class Solution {
    private int getNext(int n) {
        int totalSum = 0;
        while (n > 0) {
            int d = n % 10;
            n = n / 10;
            totalSum += d * d;
        }
        return totalSum;
    }

    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;
    }
}

方法二:数学

class Solution {

    private static Set<Integer> cycleMembers =
        new HashSet<>(Arrays.asList(4, 16, 37, 58, 89, 145, 42, 20));

    public int getNext(int n) {
        int totalSum = 0;
        while (n > 0) {
            int d = n % 10;
            n = n / 10;
            totalSum += d * d;
        }
        return totalSum;
    }


    public boolean isHappy(int n) {
        while (n != 1 && !cycleMembers.contains(n)) {
            n = getNext(n);
        }
        return n == 1;
    }
}
相关文章
|
移动开发 vr&ar
数据库系统概论——关系代数详解
关系代数是一种抽象的查询语言,是关系数据操纵语言的一种传统表达方式,它是利用对关系的运算来表达查询的。任何运算都是将一定的运算符作用于一定的运算对象上,得到预期的运算结果。关系代数的运算对象是关系,运算结果亦为关系。集合运算符将关系看成元组的集合从关系的“水平”方向即行的角度来进行运算专门的关系运算符不仅涉及行而且涉及列算术比较符辅助专门的关系运算符进行操作逻辑运算符辅助专门的关系运算符进行操作。
1328 1
数据库系统概论——关系代数详解
|
关系型数据库 MySQL Linux
Centos7 yum如何下载离线安装包?(详解)
相信大家也遇到过这种问题,在没有外网的情况下,想安装一个服务却安装不了,这期我就教大家如何如何下载离线安装包,在内网中使用;
2438 0
Centos7 yum如何下载离线安装包?(详解)
|
Windows
Windows——如何在文件资源管理器地址栏快速打开Vscode
Windows——如何在文件资源管理器地址栏快速打开Vscode
257 4
|
7月前
|
机器学习/深度学习 算法 数据可视化
基于线性核函数的SVM数据分类算法matlab仿真
本程序基于线性核函数的SVM算法实现数据分类,使用MATLAB2022A版本运行。程序生成随机二维数据并分为两组,通过自定义SVM模型(不依赖MATLAB工具箱)进行训练,展示不同惩罚参数C下的分类结果及决策边界。SVM通过寻找最优超平面最大化类别间隔,实现高效分类。 核心代码包括数据生成、模型训练和结果可视化,最终绘制了两类数据点及对应的决策边界。此实现有助于理解SVM的工作原理及其在实际应用中的表现。
|
人工智能 安全 搜索推荐
AI智能体研发之路-模型篇(三):中文大模型开、闭源之争
AI智能体研发之路-模型篇(三):中文大模型开、闭源之争
320 1
|
消息中间件 Java API
Java一分钟之-JMS:Java消息服务
【6月更文挑战第11天】Java消息服务(JMS)是企业应用中实现组件解耦和异步通信的标准API。它包含点对点(P2P)和发布/订阅(Pub/Sub)两种消息模型。常见问题包括混淆消息模型、忽略事务管理和资源泄露。解决方法包括明确业务需求选择模型、使用事务确保消息可靠性以及正确关闭资源。文中提供了使用ActiveMQ的P2P模型的生产者和消费者代码示例,强调理解基础概念、避免问题以及实践是使用JMS的关键。
463 2
|
Kubernetes 关系型数据库 网络架构
ray集群部署vllm的折磨
概括如下: 在构建一个兼容多种LLM推理框架的平台时,开发者选择了Ray分布式框架,以解决资源管理和适配问题。然而,在尝试集成vllm时遇到挑战,因为vllm内部自管理Ray集群,与原有设计冲突。经过一系列尝试,包括调整资源分配、修改vllm源码和利用Ray部署的`placement_group_bundles`特性,最终实现了兼容,但依赖于非官方支持的解决方案。在面对vllm新版本和Ray部署的`reconfigure`方法问题时,又需权衡和调整实现方式。尽管面临困难,开发者认为使用Ray作为统一底层仍具有潜力。
|
iOS开发 MacOS Python
如何配置 OpenAI 环境变量
如何配置 OpenAI 环境变量
455 0
|
搜索推荐
CSDN自定义模块全攻略,DIY系统原有样式打造出你的专属个性化主页!
CSDN自定义模块全攻略,DIY系统原有样式打造出你的专属个性化主页!
365 0
|
Ubuntu Shell Linux
shell配置以及安装
shell配置以及安装
271 2