ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【LeetCode - Java】202. 快乐数 (简单)

2022-02-09 17:04:55  阅读:166  来源: 互联网

标签:10 202 Java int sum while 哈希 return LeetCode


目录

1. 题目描述

在这里插入图片描述

2. 解题思路

这道题目的逻辑是很简单的,难点是在于如何判断已经循环够了,该跳出循环了?首先,如果这个数是快乐数,最终会等于1,那么就可以直接跳出循环并返回了;但是,如果这个数不是快乐数,他就会无限循环,那还有什么规律吗?我发现,对于10以下的数,只有1和7是快乐数,其他都不是,那么这就意味着当我迭代发现当前数是小于10并且不是71时,就该结束循环返回false了,这种解法我称之为规律法,可能并不是十分正统的思路。

那么有其他正统的思路吗?如果我能记住我之前判断过什么数字,当我又重新遇到这个数字的时候,那不就代表着存在死循环,可以返回false了。实现方法自然而然就想到了哈希表

既然说遇到某个数字会产生死循环,那么是不是特定的几个数字呢?我手写推算了几位数字发现,对于非快乐数而言最终都会掉进4, 16, 37, 58, 89, 145, 42, 20这个循环当中,那就意味着只要在迭代过程中的数是以上之一,那么他就不是快乐数了,这是基于记忆(哈希表)和规律的思路。

循环,相当于一个链表中拥有回路,在【LeetCode - Java】141. 环形链表 (简单)中介绍过一种高效的快慢指针算法,可以快速地进行判断,对于这一道题目是同样适用的。

3. 代码实现

3.1 规律法

public boolean isHappy(int n) {
        int sum;
        while (n != 1) {
            if (n < 10 && n != 7)
                return false;
            sum = 0;
            while (n != 0) {
                sum += (int) Math.pow(n % 10, 2);
                n /= 10;
            }
            n = sum;
        }
        return true;
    }

3.2 哈希表

public boolean isHappy(int n) {
        HashSet<Integer> set = new HashSet<>();
        int sum;
        while (!set.contains(n)) {
            set.add(n);
            sum = 0;
            while (n != 0) {
                sum += Math.pow(n % 10, 2);
                n /= 10;
            }
            if (sum == 1)
                return true;
            n = sum;
        }
        return false;
    }

3.3 哈希表+规律

public boolean isHappy(int n) {
        HashSet<Integer> set = new HashSet<>(Arrays.asList(4, 16, 37, 58, 89, 145, 42, 20));
        while (!set.contains(n)) {
            if (n == 1)
                return true;
            int sum = 0;
            while (n != 0) {
                sum += Math.pow(n % 10, 2);
                n /= 10;
            }
            n = sum;
        }
        return false;
    }

3.4 快慢指针

public boolean isHappy(int n) {
        int slow = n;
        int fast = next(next(n));
        while (slow != fast && fast != 1) {
            slow = next(slow);
            fast = next(next(fast));
        }
        return fast == 1;
    }

    public int next(int n) {
        int sum = 0;
        while (n != 0) {
//            sum += Math.pow(n % 10, 2);
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }

3.5 对比

理论上,上述所有方法的时间复杂度都是线性复杂度,因此时间差异都不大,哈希表的时间消耗较大应该是哈希表的存储查询导致的。另外,一个很有意思的点是在快慢指针算法当中,我尝试自己使用乘法进行平方运算,结果发现比使用Math.pow函数内存消耗更低
在这里插入图片描述

标签:10,202,Java,int,sum,while,哈希,return,LeetCode
来源: https://blog.csdn.net/weixin_45453739/article/details/122844301

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有