【LeetCode哈希表#3】快乐数(set)
快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
初见思路
题意不难理解
步骤大致可以拆分成:
1、获取输入整数各位上的数
2、做平方后相加
3、重复上述过程
显然需要有一个循环计算的过程,那么结束条件是sum为1,但要是出现无限循环(sum一直不为1)的情况,那程序就卡死了
如何处理上述情况?
思路
本题的两个关键点:取各个数位上的单个数、循环结束条件
取各个数位上的单个数
先再次复习一下编程中的两种除法操作:取整和取余(取模)
在c++中,
"/"是做取整数的除法,例如:19/10 = 1.9 = 1
"%"是做取除法但是取余数的值,例如:19%10 = 1余9 = 9
那么,可以先用10来和输入整数做取余运算来不断获取整数的个位数,然后通过取整运算将已经获取的数去除
如此循环到只剩下一位数,其再做除法得小数,经过取整后得0,此时循环结束
void getEechNum(int n) {
int curNum;
cout << "从个位开始的每个数为:" << endl;
while (n) {//同时,以n作为循环结束条件
curNum = n % 10;//获取当前个位上的数
cout << curNum << endl;
n /= 10;//去除已获取到的数
}
}
int main() {
getEechNum(156);
}
题中要求取到整数的每个单个数后做平方运算,因此用来取每个数的函数可以写成:
// 取数值各个位上的单数之和
int getSum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);//直接在这里做平方运算
n /= 10;
}
return sum;
}
循环结束条件
通过题目可知,“快乐数”的计算过程可能会出现无限循环的情况
例如,输入整数A,经过10次计算后sum = A
这就进入无限循环了,那么整数A也就不可能是快乐数
上述现象可以作为判断快乐数时循环结束的条件
具体处理上,我们可以让每次计算得到的sum保存到unordered_set中,一旦出现重复值(涉及判断重复值的,直接联想哈希表),即可作出判断。
代码
class Solution {
public:
int getSum(int n){
int sum = 0;
while(n){
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
//定义一个unordered_set
unordered_set<int> set;
//4、循环计算过程,知道找出快乐数或者陷入死循环
while(1){
//1、获取输入整数每各数位上的数的平方和
int sum = getSum(n);
//2、判断和是否为1
if (sum == 1) {
return true;
}else if(set.find(sum) != set.end()){//如果sum值在set中出现过,则陷入循环
return false;
}else{
set.insert(sum);
}
//3、不为1则更新n值继续计算
n = sum; //重复对sum进行上述运算
}
}
};