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

【LeetCode】202. 快乐数

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 <= 23^1 - 1

个人题解

方法一:模拟

一开始想先写出最简单的方式,尝试打表找规律,打表发现没规律0.0

思路:

  1. 本题主要是要解决 无限循环 的问题,用 hashSet 容器存储已经考虑过的数字便可得到,当再次算回容器中数字便表示将会 无限循环,返回 false 即可
class Solution {
    public boolean isHappy(int n) {
        HashSet<Integer> set = new HashSet<>();
        set.add(n);
        while (n != 1) {
            int sum = 0;
            while (n >= 10) {
                sum += (int) Math.pow(n % 10, 2);
                n /= 10;
            }
            n = sum + n * n;
            if (set.contains(n)) {
                return false;
            }
            set.add(n);
        }
        return true;
    }
}

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(log n)

官方题解

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

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

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(log n)
方法二:快慢指针法

通过反复调用 getNext(n) 得到的链是一个隐式的链表。隐式意味着我们没有实际的链表节点和指针,但数据仍然形成链表结构。起始数字是链表的头 “节点”,链中的所有其他数字都是节点。next 指针是通过调用 getNext(n) 函数获得。

意识到我们实际有个链表,那么这个问题就可以转换为检测一个链表是否有环。因此我们在这里可以使用弗洛伊德循环查找算法。这个算法是两个奔跑选手,一个跑的快,一个跑得慢。在龟兔赛跑的寓言中,跑的慢的称为 “乌龟”,跑得快的称为 “兔子”。

不管乌龟和兔子在循环中从哪里开始,它们最终都会相遇。这是因为兔子每走一步就向乌龟靠近一个节点(在它们的移动方向上)。

我们不是只跟踪链表中的一个值,而是跟踪两个值,称为快跑者和慢跑者。在算法的每一步中,慢速在链表中前进 1 个节点,快跑者前进 2 个节点(对 getNext(n) 函数的嵌套调用。

如果 n 是一个快乐数,即没有循环,那么快跑者最终会比慢跑者先到达数字 1

如果 n 不是一个快乐数,那么最终快跑者和慢跑者将在同一个数字上相遇。

class Solution {

     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) {
        int slowRunner = n;
        int fastRunner = getNext(n);
        while (fastRunner != 1 && slowRunner != fastRunner) {
            slowRunner = getNext(slowRunner);
            fastRunner = getNext(getNext(fastRunner));
        }
        return fastRunner == 1;
    }
}
  • 复杂度分析

    • 时间复杂度:O(log n)
    • 空间复杂度:O(1)

作者:力扣官方题解
链接:https://leetcode.cn/problems/happy-number/solutions/224894/kuai-le-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


http://www.kler.cn/a/162210.html

相关文章:

  • ESLint 使用教程(五):ESLint 和 Prettier 的结合使用与冲突解决
  • 【力扣热题100】[Java版] 刷题笔记-169. 多数元素
  • 从华为到创业公司
  • 信号-3-信号处理
  • Elasticsearch 实战应用:高效搜索与数据分析
  • Vue 的生命周期函数 和 Vuex
  • crmeb本地开发配置代理
  • 过滤器Filter实现及执行顺序
  • 销售技巧培训之如何提高手机销售技巧
  • 机器学习应用 | 使用 MATLAB 进行异常检测(下)
  • 销售技巧培训之如何提升顾问式销售技巧
  • 传世SUN引擎如何安装
  • RabbitMq整合Springboot超全实战案例+图文演示+源码自取
  • MacBook 逆水寒下载安装使用教程,支持最新版本 MacOS 流畅不闪退
  • 如何解压没有密码的7-zip文件?
  • 如何解决5G基站高能耗问题?
  • 工业机器视觉megauging(向光有光)使用说明书(二,轻量级的visionpro)
  • 柏林噪声C++
  • 小白学java栈的经典算法问题——第四关白银挑战
  • jsp 分页查询展示,实现按 上一页或下一页实现用ajax刷新内容
  • SSL证书代理
  • 使用navicat(或者其他数据库管理工具)、powerdesigner导出数据字典
  • [MySQL--基础]多表查询
  • 刷题记录--算法--简单
  • Python---time库
  • CSS Grid布局入门:从零开始创建一个网格系统