数据结构与算法-33.快乐数

本文探讨了快乐数问题的三种解决方案:暴力解法利用哈希集合判断循环,快慢指针通过两个指针检测循环,以及数学方法仅关注特定循环序列。详细讲解了每种方法的时间复杂度和空间复杂度,并强调了它们在判断数字是否构成快乐数循环上的应用。
摘要由CSDN通过智能技术生成

33、快乐数

题目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qIDbclqR-1638794994523)(image-20211206204037561.png)]

33.0、暴力解法

先写一个函数来计算每个位置的平方和,该函数对于下列三种方法通用

int calculate(int n)
{
    int m = 0;
    while (n)
    {
        m += (int)pow(n % 10, 2);
        n /= 10;
    }
    return m;
}

暴力解法比较实际,用一个哈希集合来记录每次的数从而来判断是否存在循环

//暴力解法
bool isHappy0(int n) 
{
    unordered_set<int> data;
    while (!data.count(n))
    {
        if (n == 1)return true;
        data.insert(n);
        n = calculate(n);
    }
    return false;
}

时间复杂度:O(log n)对于通用函数的时间复杂度是log n,从开始到1或者发现循环的个数是常量(数学上可以证明)

空间复杂度:不一定,我直接一个不一定

33.1、快慢指针

这个和那个判断链表是否存在环类似,使用一前一后两个指针来判断是否在存在循环

//快慢指针
bool isHappy1(int n)
{
    int slownum = n, fastnum = calculate(n);
    while (fastnum != 1 && slownum != fastnum)
    {
        slownum = calculate(slownum);
        fastnum = calculate(calculate(fastnum));
    }
    return fastnum == 1;
}

时间复杂度:O(log n)同上

空间复杂度:O(1)

33.2、数学

研究一下可以发现,只有一个循环【4,16,37,58,89,145,42,,20 ,4】

所以只需要判断每一次的数是否在这个序列里面就可以判断是否存在循环了

//数学方法
bool isHappy2(int n)
{
    unordered_set<int> data = { 4, 16, 37, 58, 89, 145, 42, 20 };
    while (!data.count(n))
    {
        if (n == 1)return true;
        n = calculate(n);
    }
    return false;
}

时间复杂度:O(log n)同上

空间复杂度:O(1)集合是一个常量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值