我是一个从汽车行业转行IT的项目经理,我是Edward,如想了解更多,请关注我的公众号【转行项目经理的逆袭之路】。今天是五一长假前的最后一天,其实想想,对于有稳定工作的人来说,今年也真是爽,上半年假就像休不完一样,连leetcode的每日一题在今天都抛出了快乐数这个题,让我们一起来看看吧。
202. 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
分析
将题目分为两个问题,1.各位数平方之和的算法 2.无限循环如何处理
第一个问题很简单,第二个问题就有点棘手了,好在我们可以查百度:
不是快乐数的数称为不快乐数(unhappy number),所有不快乐数的数位平方和计算,最後都会进入 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 的循环中。
用一句话形容就是:每个快乐数都有相同的happy ending,而每个不快乐数都在不快乐中无限循环。
思路
既然知道了不快乐数的各位数平方和会形成一个环,那么我们就可以用快慢指针来解决,慢的走一步,快的走两步,循环一次就相遇,慢指针遍历了所有结点,如果相遇时慢指针不为1则不是快乐数(注意:如果在中间出现1,后面的所有平方和均会是1)。
关于快慢指针,是解决链表问题的经典方法,具体可以参看这篇文章:
https://www.cxyxiaowu.com/7913.html
实现
package algorithm;
/**
* 202. Happy Number
* Input: 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
* @author EP
* @date 2020年4月30日
* @version 1.0
*/
public class Solution_isHappy {
public static void main(String[] args) {
int n = 19;
System.out.println(isHappy(n));
}
public static boolean isHappy(int n) {
//快慢指针,相遇即为一次循环,为1则永远为1
int slow = n; int fast =squareSum(n);
while (slow!=fast) {
//fast每次都快走一步
slow = squareSum(slow);
fast=squareSum(squareSum(fast));
}
return slow==1;
}
public static int squareSum(int n) {
int sum=0;
while (n>0) {
int digit = n%10;
sum+=digit*digit;
n/=10;
}
return sum;
}
}
好了,告诉我,今天你快乐了吗?