LeetCode 面试经典 150_哈希表_快乐数(45_202_C++_简单)(哈希表;快慢指针)
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),只进行计算没有使用哈希表。
代码实现
代码实现(思路一(哈希表)):
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;}// 如果平方和已经出现过,说明进入了循环,返回falseif (set.count(sumOfSquares)) {return false;}// 插入当前平方和,准备下一轮计算set.insert(sumOfSquares);// 赋值给n,继续进行下一轮计算n = sumOfSquares;}// 如果n最终变成1,说明是快乐数return true;}
};
代码实现(思路二(快慢指针)):
class Solution2 {
private:// 计算数字各位数字的平方和int bitSquareSum(int n){int sumOfSquares = 0; // 初始化平方和为0while (n > 0) {int bit = n % 10; // 取数字的最后一位sumOfSquares += bit * bit; // 累加该位数字的平方n /= 10; // 移除最后一位数字}return sumOfSquares; // 返回计算出来的平方和}public:// 判断一个数是否为快乐数bool isHappy(int n) {int slow = n; // 慢指针,初始为nint 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}
};
以思路一为例进行调试
#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;}// 如果平方和已经出现过,说明进入了循环,返回falseif (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)原题链接
欢迎大家和我沟通交流(✿◠‿◠)