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),只进行计算没有使用哈希表。

代码实现

代码实现(思路一(哈希表)):
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)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
z200509309 分钟前
今日算法(回溯找IP,加检测)
算法·leetcode
sheeta199814 分钟前
LeetCode 补拙笔记 日期:2026.05.29 题目:1559. 二维网格图中探测环
笔记·算法·leetcode
罗超驿15 分钟前
10.滑动窗口解决:无重复字符的最长子串 | LeetCode 3 Java 题解
java·算法·leetcode·面试
罗超驿15 分钟前
8.【LeetCode 18】四数之和 —— Java 排序 + 双指针解法详解
算法·leetcode·职场和发展
海南java第二人18 分钟前
ClickHouse 实际应用类面试通关:项目案例、生产踩坑与实战经验
clickhouse·面试·实际应用类
野生技术架构师19 分钟前
2026最新Java面试1200题全解析:从基础到架构,覆盖所有技术栈(含答案)
java·面试·架构
菜菜的顾清寒19 分钟前
HOT100力扣(40) 动态规划-爬楼梯
算法·leetcode·动态规划
西安邮电大学1 小时前
Kafka如何避免重复消费
java·后端·其他·面试·kafka
闪电悠米1 小时前
黑马点评-优惠券秒杀-03_basic_seckill_and_oversell
java·数据库·spring boot·spring·缓存·oracle·面试
羑悻的小杀马特1 小时前
【动态规划篇】正则表达式与通配符:开启代码匹配的赛博奇幻之旅
c++·算法·leetcode·正则表达式