当前位置: 首页 > news >正文

leetcode 面试经典 150 题:快乐数

链接快乐数
题序号202
题型数组
解题方法哈希表
难度简单
熟练度✅✅✅✅

题目

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

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

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

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

  • 提示:
    1 <= n <= 231 - 1

题解

  1. 核心思想:使用哈希表来记录已经出现过的数字,如果在计算过程中某个数字重复出现,说明进入了循环,返回 false;如果最终计算结果为 1,返回 true。
  2. 复杂度:时间复杂度O(logn),因为每次计算下一个数的时间复杂度为 O(logn);空间复杂度O(1),不需要额外的存储空间。
  3. c++ 实现算法
class Solution {
public:bool isHappy(int n) {unordered_set<int> seen; // 用于存储已经出现过的数字,检测循环//如果 find(n) 返回 seen.end(),表示 n 不存在于集合中,查找失败。//如果 find(n) 返回的迭代器不是 seen.end(),表示 n 存在于集合中,查找成功。while (n != 1 && seen.find(n) == seen.end()) {seen.insert(n);     // 将当前数字加入集合n = getNext(n);     // 计算下一步的平方和}return n == 1;          // 如果 n == 1,返回 true;否则进入循环,返回 false}private:int getNext(int n) {int sum = 0;while (n > 0) {int digit = n % 10; // 提取个位数,如果 n = 123,则 digit = 123 % 10 = 3sum += digit * digit; // 累加平方n /= 10;             // 去掉个位,如果 n = 123,执行 n /= 10 后,n = 12}return sum;}
};
  1. 算法推演
  • 初始值: 输入数字:n = 2 seen 集合:空集合 {}

  • 第一步:计算平方和
    当前数字:n = 2
    计算平方和: 22=4
    更新数字:n = 4 检查 4 是否在 seen 集合中:否,将 4 加入集合。
    集合更新为:{2}

  • 第二步:计算平方和
    当前数字:n = 4
    计算平方和: 42=16
    更新数字:n = 16 检查 16 是否在 seen 集合中:否,将 16 加入集合。
    集合更新为:{2, 4}

  • 第三步:计算平方和
    当前数字:n = 16
    计算平方和: 12+62=37
    更新数字:n = 37 检查 37 是否在 seen 集合中:否,将 37 加入集合。
    集合更新为:{2, 4, 16}

  • 第四步:计算平方和
    当前数字:n = 37
    计算平方和: 32+72=58
    更新数字:n = 58 检查 58 是否在 seen 集合中:否,将 58 加入集合。
    集合更新为:{2, 4, 16, 37}

  • 第五步:计算平方和
    当前数字:n = 58
    计算平方和: 52+82=89
    更新数字:n = 89 检查 89 是否在 seen 集合中:否,将 89 加入集合。
    集合更新为:{2, 4, 16, 37, 58}

  • 第六步:计算平方和
    当前数字:n = 89
    计算平方和: 82+92=145
    更新数字:n = 145 检查 145 是否在 seen 集合中:否,将 145 加入集合。
    集合更新为:{2, 4, 16, 37, 58, 89}

  • 第七步:计算平方和
    当前数字:n = 145
    计算平方和: 12+42+52=42
    更新数字:n = 42 检查 42 是否在 seen 集合中:否,将 42 加入集合。
    集合更新为:{2, 4, 16, 37, 58, 89, 145}

  • 第八步:计算平方和
    当前数字:n = 42
    计算平方和: 42+22=20
    更新数字:n = 20 检查 20 是否在 seen 集合中:否,将 20 加入集合。
    集合更新为:{2, 4, 16, 37, 58, 89, 145, 42}

  • 第九步:计算平方和
    当前数字:n = 20
    计算平方和: 22+02=4
    更新数字:n = 4 检查 4 是否在 seen 集合中:是,说明进入循环。

  • 结论
    输入 2 会进入循环,无法到达 1,因此 2 不是一个快乐数。

  • 循环检测
    通过集合 seen,我们检测到了循环路径: 2 → 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 (循环) 这是算法检测非快乐数的重要机制,避免了死循环。

  1. c++ 完整demo
#include <iostream>
#include <unordered_set>
using namespace std;class Solution {
public:bool isHappy(int n) {unordered_set<int> seen; // 用于存储已经出现过的数字,检测循环//如果 find(n) 返回 seen.end(),表示 n 不存在于集合中,查找失败。//如果 find(n) 返回的迭代器不是 seen.end(),表示 n 存在于集合中,查找成功。while (n != 1 && seen.find(n) == seen.end()) {seen.insert(n);     // 将当前数字加入集合n = getNext(n);     // 计算下一步的平方和}return n == 1;          // 如果 n == 1,返回 true;否则进入循环,返回 false}private:int getNext(int n) {int sum = 0;while (n > 0) {int digit = n % 10; // 提取个位数,如果 n = 123,则 digit = 123 % 10 = 3sum += digit * digit; // 累加平方n /= 10;             // 去掉个位,如果 n = 123,执行 n /= 10 后,n = 12}return sum;}
};int main() {Solution solution;int n = 2;if (solution.isHappy(n)) {cout << n << " is a happy number!" << endl;} else {cout << n << " is not a happy number!" << endl;}return 0;
}
http://www.lryc.cn/news/520359.html

相关文章:

  • Leetcode 279. 完全平方数 动态规划 完全背包问题
  • python学opencv|读取图像(三十三)阈值处理图像-限定像素
  • QT Quick QML 实例之椭圆投影,旋转
  • 炸砖块游戏的最终图案
  • LLM的实验平台有哪些:快速搭建测试大语言模型
  • python3GUI--大屏可视化-XX产业大数据指挥舱(附下载地址) By:PyQt5
  • .NET 9.0 的 Blazor Web App 项目中 Hash 变换(MD5、Pbkdf2) 使用备忘
  • uniapp 抖音小程序 getUserProfile:fail must be invoked by user tap gesture
  • (undone) MIT6.S081 2023 学习笔记 (Day5: LAB4 traps)
  • 前端笔记----
  • 学习华为熵减,激发组织活力
  • 9Hive数据倾斜
  • 【大数据】机器学习 -----关于data.csv数据集分析案例
  • 深入解析 C++ 类型转换
  • C++ union 联合(八股总结)
  • 聊聊AI Agent
  • scala代码打包配置(maven)
  • 慧集通(DataLinkX)iPaaS集成平台-业务建模之业务对象(二)
  • C++使用minio-cpp库在minio中创建bucket
  • 【大模型】大语言模型的数据准备:构建高质量训练数据的关键指南
  • 【解决】okhttp的java.lang.IllegalStateException: closed错误
  • TCP-IP详解卷 TCP的超时与重传
  • Linux服务器查看【可用端口号连接】的命令和方式【netstat,ss,lsof】
  • 【WPS】【WORDEXCEL】【VB】实现微软WORD自动更正的效果
  • Attention计算中的各个矩阵的维度都是如何一步步变化的?
  • 【数模学习笔记】插值算法和拟合算法
  • 探索 C++ 与 LibUSB:开启 USB 设备交互的奇幻之旅
  • 二、模型训练与优化(4):模型优化-实操
  • 3D可视化产品定制,应用于哪些行业领域?
  • Avalonia 入门笔记(零):概述