力扣—快乐数—双指针—C语言Java实现

题目解析

「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 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个巢,N+1个鸽,至少有一个巢的鸽子数大于1,例如数字9999他执行快乐数是数字变化的范围是[1,243],最坏的情况在执行前面243次的时候每个位置都占了一个鸽子,但是在执行244次的时候总有一个巢穴鸽子数大于1,这个时候就变成了第二种情况形成了一个循环,得到的链是一个隐式的链表。隐式意味着我们没有实际的链表节点和指针,但数据仍然形成链表结构。起始数字是链表的头 “节点”,链中的所有其他数字都是节点。如果循环到最后数字是1,那就是快乐数,否则就不是快乐数。问题就转化为判断检测一个链表是否有环。因此我们在这里可以使用弗洛伊德循环查找算法。这个算法是两个奔跑选手,一个跑的快(一次跑两步),一个跑得慢(一次跑一步)。在龟兔赛跑的寓言中,跑的慢的称为 “乌龟”,跑得快的称为 “兔子”。

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

代码实现

C语言实现

int Sum(int n)
{
	int sum=0;
	while(n)
	{
	 int num=n%10;
	 sum=sum+num*num;
	 n=n/10;
	}
	return sum;
} 
bool isHappy(int n) 
{
    int low=n;
    int fast=Sum(n);
    while(low!=fast)
    {
		low=Sum(low);
		fast=Sum(Sum(fast));
	}
	return low==1;
}

Java实现

class Solution {
    public int Sum(int n)
    {
        int sum=0;
        int num=0;
        while(n!=0)
        {
            num=n%10;
            sum=sum+num*num;
            n=n/10;
        }
        return sum;
    }
    public boolean isHappy(int n) 
    {
      int low=n;
      int fast=Sum(n);
      while(low!=fast)
      {
        low=Sum(low);
        fast=Sum(Sum(fast));
      }
      return low==1;
    }
}

欢迎留言讨论

  • 22
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缘来如此҉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值