Leetcode 题解 - 202. Happy Number

题目

编写一个算法,判断一个数是否“快乐数”。

快乐数的定义是:对于一个正整数,用各个位的平方和替换这个正整数,一直循环直到正整数为 1(并能一直保持),或循环因为不包含 1 而无法停止。那些循环最终得到 1 的数是快乐数。

示例

19 是快乐数:

  • 12 + 92 = 82
  • 82 + 22 = 68
  • 62 + 82 = 100
  • 12 + 02 + 02 = 1

难度:容易

编程语言:C++


分析

程序框架为:

1
2
3
4
5
6
class Solution {
public:
bool isHappy(int n) {
}
};

示例里给出的 19 是快乐数,那么我们看看不是快乐数的执行过程是怎样的,试试 20:

  • 22 + 02 = 4
  • 42 + 02 = 16
  • 12 + 62 = 37
  • 32 + 72 = 58
  • 52 + 82 = 89
  • 82 + 92 = 145
  • 12 + 42 + 52 = 42
  • 42 + 22 = 20
  • 22 + 02 = 4 // 与第 1 行循环了

可以看到,上述的执行过程出现死循环,无法收敛到 1,所以 20 不是快乐数。

为了检查是否会出现死循环,我们需要一个 vector 保存所有平方和。在添加一个平方和之前,遍历 vector 检查是否与已保存的相同,如果是,说明会形成死循环,n 不是快乐数。如果一直添加,直到添加 1,那么 n 是快乐数。

伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool isHappy(int n) {
if (n < 1) {
return false;
}
vector<int> v;
while (true) {
int sumSquare = getSumSquare(n);
if (sumSquare == 1) {
return true;
}
if (containsElement(v, sumSquare)) { // 死循环
return false;
}
v.push_back(sumSquare);
n = sumSquare; // 更新 n
}
}

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
bool isHappy(int n) {
if (n < 1) {
return false;
}
vector<int> v;
while (true) {
int sumSquare = getSumSquare(n);
if (sumSquare == 1) {
cout << "sumSquare == 1,return true" << endl;
return true;
}
if (containsElement(v, sumSquare)) { // 死循环
cout << "vector 已存在 " << sumSquare << ",死循环,return false" << endl;
return false;
}
v.push_back(sumSquare);
cout << "vector 添加 " << sumSquare << endl;
n = sumSquare; // 更新 n
}
}
// 求 n 各位数字的平方和
int getSumSquare(int n) {
int sumSquare = 0;
while (n > 0) {
int digit = n % 10;
sumSquare += digit * digit;
n /= 10;
}
return sumSquare;
}
bool containsElement(vector<int> v, int n) {
for (int element : v) {
if (element == n) {
return true;
}
}
return false;
}
};
int main() {
Solution sol;
cout << sol.isHappy(19) << endl << endl;
cout << sol.isHappy(20) << endl << endl;
}
// 输出结果:
// vector 添加 82
// vector 添加 68
// vector 添加 100
// sumSquare == 1,return true
// 1
//
// vector 添加 4
// vector 添加 16
// vector 添加 37
// vector 添加 58
// vector 添加 89
// vector 添加 145
// vector 添加 42
// vector 添加 20
// vector 已存在 4,死循环,return false
// 0
//

提交到 Leetcode,Accepted! :) 运行时间为 40ms。