力扣-202. 快乐数解析-弗洛伊德循环查找算法

题目链接

复制代码
public static void Happy(int n) {
        int sum = 0;
        int digit = 0;
        for (int i = 0; i < 20; i++) {
            while (n != 0) {
                digit = n%10;
                sum += digit*digit;
                n/=10;
            }
            System.out.print(sum + " ");
            n = sum;
            sum = 0;
        }
    }

使用代码测试一下每一代数字

复制代码
n = 2 :
4 16 37 58 89 145 42 20 4 16 37 58 89 145 42 20 4 16 37 58 
n = 3 :
9 81 65 61 37 58 89 145 42 20 4 16 37 58 89 145 42 20 4 16 
n = 4 :
16 37 58 89 145 42 20 4 16 37 58 89 145 42 20 4 16 37 58 89 
n = 5 :
25 29 85 89 145 42 20 4 16 37 58 89 145 42 20 4 16 37 58 89 
n = 6 :
36 45 41 17 50 25 29 85 89 145 42 20 4 16 37 58 89 145 42 20 
n = 7 :
49 97 130 10 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

可以发现

归纳一下这些简单数字就可以发现,对于任意一个非快乐数,最终会进入重复循环, ···不难发现,4即之后的结果就是新一轮循环。

那么我的第一个做法是检测4出现的次数 如果4出现次数超过两次, 那么就不是快乐数

复制代码
{
        int sum = 0;
        int n1 = n;
        int count = 0;
        for (int i = 0;  ; i++) {
            while (true) {
                int a = n%10;
                sum += a*a;
                n /= 10;
                if (n == 0){break;}
            }
            if (sum==4){
                count++;
            }
            if (sum==1){return true;}
            if (count==2){return false;}
            n = sum;
            sum=0;
        }

    }

感觉不太行

想了一想 其实这道题为弗洛伊德查找算法提供了很好的条件

弗洛伊德查找算法原理见此处链接

代码如下:

复制代码
{
    //弗洛伊德循环查找算法
    public static boolean isHappy(int n) {
        int slow = n;
        int fast  = n;
        while (true) {
            slow = Next(slow);
            fast = Next(Next(fast));
            if (fast == 1) {
                return true;
            } else if (fast == slow) {
                return false;
            }
        }
    }
    public static int Next(int n){
        int sum = 0;
        while (n != 0){
            int digit = n % 10;
            sum += digit*digit;
            n /= 10;
        }
        return sum;
    }
    public static void main(String[] args) {
        System.out.println(isHappy(19));
    }
}

当测试用例为2这个数字的时候

复制代码
4 16 37 58 89 145 42 20 4 16 37 58 89 145 42 20 4 16 37 58 

第一步初始化slow和fast两个指针为头结点 (就是2)

第一次更新值

第二次

第三次

第四次

第五次

第六次

第七次

第八次

此时slow== fast

发现为循环链表(这里没有存储之前的值算不上链表)

return false

舒服了

如果觉得有用请点赞收藏, 谢谢啦

相关推荐
我是人✓4 分钟前
SQL主键与外键
java·数据库
圣光SG11 分钟前
Java操作题练习(二)
java·开发语言·python
m0_6174939412 分钟前
Python OpenCV 分水岭算法(Watershed)详解与实战
python·opencv·算法
海带紫菜菠萝汤13 分钟前
企业批量PDF翻译方案:从选型到部署的完整指南
人工智能·算法·pdf
蜡台16 分钟前
Android WebView 设计指南
android·java·kotlin
贵慜_Derek28 分钟前
vLLM-05|MLA、Compressor、Indexer 与 SWA:Flash 注意力栈在 vLLM 里怎么落地
人工智能·算法·llm
菜鸟的升级路28 分钟前
C语言栈刷题:LeetCode 20 有效的括号完整解题笔记
c语言·笔记·leetcode
冻柠檬飞冰走茶30 分钟前
PTA基础编程题目集 7-13 日K蜡烛图(C语言实现)
c语言·开发语言·数据结构·算法
AI_paid_community32 分钟前
机械研发人员如何使用 Claude?
java·vue.js
MacroZheng34 分钟前
同事:“Claude Code都能自动写代码了,还要什么Spec Coding?” 我反问:“屎山代码你来维护?”
java·人工智能·后端