LeetCode 面试经典 150_哈希表_快乐数(45_202_C++_简单)
题目描述:
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
输入输出样例:
示例 1:
输入 :n = 19
输出 :true
解释 :
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
示例 2:
输入 :n = 2
输出:false
提示:
1 <= n <= 231 - 1
题解:
解题思路:
思路一(哈希表):
1、将整数按位进行拆分,计算拆分后数字的平方和。直至拆分后数字的平方和为 1 或者无限循环。
2、复杂度分析:
① 时间复杂度:O(log n)。对于一个数字 n,它最多会有大约 log(n) 位数。对于每一轮平方和计算,时间复杂度是 O(log n)。
② 空间复杂度:O(logn),主要是哈希表所消耗的空间。
思路二(快慢指针):
1、存在环的话 慢指针 一定会和 快指针相遇(慢指针走一步,快指针走两步)。
2、复杂度分析
① 时间复杂度:O(log n)
② 空间复杂度:O(1),只进行计算没有使用哈希表。
代码实现
代码实现(思路一(哈希表)):
cpp
class Solution1 {
public:
bool isHappy(int n) {
// 用int类型代替long long,因为平方和不会超出int范围
int sumOfSquares = 0;
unordered_set<int> set; // 存储计算出的平方和
while (n != 1) {
sumOfSquares = 0;
// 计算当前数字各位数字的平方和
while (n > 0) {
int bit = n % 10;
sumOfSquares += bit * bit;
n /= 10;
}
// 如果平方和已经出现过,说明进入了循环,返回false
if (set.count(sumOfSquares)) {
return false;
}
// 插入当前平方和,准备下一轮计算
set.insert(sumOfSquares);
// 赋值给n,继续进行下一轮计算
n = sumOfSquares;
}
// 如果n最终变成1,说明是快乐数
return true;
}
};
代码实现(思路二(快慢指针)):
cpp
class Solution2 {
private:
// 计算数字各位数字的平方和
int bitSquareSum(int n){
int sumOfSquares = 0; // 初始化平方和为0
while (n > 0) {
int bit = n % 10; // 取数字的最后一位
sumOfSquares += bit * bit; // 累加该位数字的平方
n /= 10; // 移除最后一位数字
}
return sumOfSquares; // 返回计算出来的平方和
}
public:
// 判断一个数是否为快乐数
bool isHappy(int n) {
int slow = n; // 慢指针,初始为n
int fast = n; // 快指针,初始为n
// 使用快慢指针法检测是否进入循环
do {
slow = bitSquareSum(slow); // 慢指针一次走一步,计算平方和
fast = bitSquareSum(fast); // 快指针先走一步,计算平方和
fast = bitSquareSum(fast); // 快指针再走一步,计算平方和(相当于快指针每次走两步)
} while (slow != fast); // 直到慢指针和快指针相遇
// 如果慢指针和快指针相遇并且是1,说明n是快乐数,否则说明是循环数
return slow == 1; // 如果slow指针为1,则说明是快乐数,返回true;否则返回false
}
};
以思路一为例进行调试
cpp
#include<iostream>
#include<unordered_set>
using namespace std;
class Solution1 {
public:
bool isHappy(int n) {
// 用int类型代替long long,因为平方和不会超出int范围
int sumOfSquares = 0;
unordered_set<int> set; // 存储计算出的平方和
while (n != 1) {
sumOfSquares = 0;
// 计算当前数字各位数字的平方和
while (n > 0) {
int bit = n % 10;
sumOfSquares += bit * bit;
n /= 10;
}
// 如果平方和已经出现过,说明进入了循环,返回false
if (set.count(sumOfSquares)) {
return false;
}
// 插入当前平方和,准备下一轮计算
set.insert(sumOfSquares);
// 赋值给n,继续进行下一轮计算
n = sumOfSquares;
}
// 如果n最终变成1,说明是快乐数
return true;
}
};
int main(int argc, char const *argv[])
{
Solution1 s1;
int n=19;
if (s1.isHappy(n)){
cout<<"true";
}else{
cout<<"false";
}
return 0;
}
LeetCode 面试经典 150_哈希表_快乐数(45_202)原题链接
欢迎大家和我沟通交流(✿◠‿◠)