编写一个算法来判断一个数 n
是不是快乐数。「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是
无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:输入:19 输出:true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02= 1
https://leetcode-cn.com/problems/happy-number/
如果一个数是快乐数,那么足够多次数的对于对每个数的平方操作再求和必定会成为1,此后不论如何操作都会是1。因此得到sum == 1时就返回真。
如果一个数不是快乐数,那么经过足够多次上述的操作,会最终进入某个有规律的闭环而无法得到1。
思路1:
设置快慢指针,若该数为快乐数,则快指针应该会比慢指针早得到1而退出循环。若快慢指针相遇,则证明该快乐数操作的序列中存在闭环,返回假。
class Solution {
public:
int separateNum(int n)
{
int res = 0;
while (n)
{
res += pow(n % 10, 2);
n /= 10;
}
return res;
}
bool isHappy(int n) {
if (n == 1) return true;//注意细节
int fast = separateNum(n), slow = n;
while (fast != slow)
{
fast = separateNum(separateNum(fast));//快指针走两倍速度
if( fast == 1)
return true;
slow = separateNum(slow);
}
return false;
}
};
思路2:
探究闭环性质。2不是一个快乐数,11也不是,对他们进行快乐数的操作会发现他们会进入4->16->37->58->89->145->42->20->4的闭环。
那么是不是当操作过程中的数有任意在闭环上就可以了呢?根据此思路得到如下代码:
class Solution {
public:
bool isHappy(int n) {
while (n != 4)//当操作到4的时候就进入闭环。
{
if (n == 1)
{
return true;
}
int sum = 0;
while (n)
{
sum += pow(n % 10,2);
n /= 10;
}
n = sum;
}
return false;
}
};
丢进判题机,AC了,具体数学证明省略。
思路3:
打哈希表,若出现第二次则直接返回假值
class Solution {
public:
bool isHappy(int n)
{
unordered_map<int,int> memo;
while (n != 1)
{
if (memo[n])
return false;
memo[n] ++;
int sum = 0;
while (n)
{
sum += pow(n % 10, 2);
n /= 10;
}
n = sum;
}
return true;
}
};
有其他解法欢迎评论哦