题目及要求
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
哈希算法
思路:每次都求出sum的平方和,因为题目说到会无限循环,用哈希去查找是否出现过,如果出现过则代表进入了无限,直接返回false,否则就一直算下去,知道n的值为1,则表示是快乐数
时间复杂度:O(log n)
空间复杂度:O(log n)
class Solution {
public:
int getsum(int n){
int sum=0;
while(n){
sum+=(n%10)*(n%10); // 求出 n 的个位数字的平方并累加到 sum 中
n/=10; // 每次都去掉 n 的个位数字
}
return sum; // 返回计算得到的平方和
}
bool isHappy(int n) {
int sum=0;
unordered_set<int> set;
while(1){ // 无限循环,直到找到结果为止
sum=getsum(n); // 调用 getsum 函数计算 n 的各个位上数字的平方和
if(sum==1) return true; // 如果平方和为 1,则说明是“快乐数”,返回 true
if(set.find(sum)!=set.end()) return false; // 如果在 set 中找到了当前的平方和,说明进入了循环,返回 false
else set.insert(sum); // 否则将当前的平方和插入到 set 中
n=sum; // 更新 n 的值为当前的平方和,继续下一轮循环
}
}
};
快慢指针思路
思路:快指针” 每次走两步,“慢指针” 每次走一步,当二者相等时,即为一个循环周期。此时,判断是不是因为 1 引起的循环,是的话就是快乐数,否则不是快乐数
参考LeetCode上的大佬的一个思路
class Solution {
public:
int quareSum(int n) {
int sum = 0;
while(n > 0)
{
sum+=(n%10)*(n%10);
n = n / 10;
}
return sum;
}
bool isHappy(int n) {
int slow = n, fast = n;
do{
slow = quareSum(slow);
fast = quareSum(fast);
fast = quareSum(fast);
}while(slow != fast);
return slow == 1;
}
};