[ LeetCode优选算法专题一双指针]---快乐数

题目链接

Leetcode快乐数

题目描述

 

如下图: 

题目解析:

 1.双指针法

算法核心思路

判断快乐数的关键挑战是如何检测是否进入无限循环。这里使用了快慢指针法(Floyd 循环检测算法),这是一种高效检测循环的技巧:

  1. 慢指针:每次计算一次数字的平方和(走一步)
  2. 快指针:每次计算两次数字的平方和(走两步)
  3. 如果是快乐数:最终都会收敛到 1,此时快慢指针会相遇在 1
  4. 如果不是快乐数:快慢指针会在某个非 1 的数字处相遇(检测到循环)

算法执行流程示例

以非快乐数 11 为例,看看算法如何工作:

  1. 初始状态:slow=11,fast=11
  2. 第一次循环:
    • slow = Sum(11) = 1² + 1² = 2
    • fast = Sum(Sum(11)) = Sum(2) = 4
    • 此时 slow≠fast,继续循环
  3. 第二次循环:
    • slow = Sum(2) = 4
    • fast = Sum(Sum(4)) = Sum(16) = 1² + 6² = 37
    • 此时 slow≠fast,继续循环
  4. 后续循环中,快慢指针会逐渐接近,最终在某个非 1 的数字相遇,此时返回 false

算法复杂度分析

  • 时间复杂度:O(log n)

    • 每次计算平方和时,数字的位数大约是 log₁₀n
    • 快慢指针相遇前最多执行 O (log n) 次操作
  • 空间复杂度:O(1)

    • 只使用了常数个额外变量,没有使用额外的数据结构

2.哈希表法 

使用哈希表(Hash Set)求解快乐数问题是另一种直观且容易理解的方法。其核心思路是记录每次计算得到的平方和,如果某个平方和重复出现,说明进入了循环,该数不是快乐数;如果最终得到 1,则是快乐数。 

哈希表解法思路 

1.计算数字的各位平方和 

2. 检查该平方和是否为 1:

     若是 1,返回 true(是快乐数)

     若不是 1,检查该平方和是否已在哈希表中: 

  • 若已存在,说明进入循环,返回 false(不是快乐数)
  • 若不存在,将其加入哈希表,继续计算下一个平方和 

 完整代码:

代码解析

  1. getSum 函数:与之前的 Sum 函数功能相同,计算一个数的各位数字平方和。

  2. isHappy 函数

    • 使用unordered_set<int> seen存储已经出现过的数字
    • 循环计算平方和,直到结果为 1 或检测到循环:
      • 若 n=1,返回 true(找到快乐数)
      • 若 n 已在哈希表中,返回 false(检测到循环)
      • 否则将 n 加入哈希表,继续计算下一个平方和

执行流程示例(以 19 为例)

  1. 初始 n=19,哈希表为空
  2. 19 不在哈希表中,加入哈希表,计算下一个值:1²+9²=82
  3. 82 不在哈希表中,加入哈希表,计算下一个值:8²+2²=68
  4. 68 不在哈希表中,加入哈希表,计算下一个值:6²+8²=100
  5. 100 不在哈希表中,加入哈希表,计算下一个值:1²+0²+0²=1
  6. 此时 n=1,返回 true(19 是快乐数)

复杂度分析

  • 时间复杂度:O(log n)

    • 每次计算平方和处理 log₁₀n 位数字
    • 最多处理 O (log n) 个不同的数字(因为平方和的增长有上限)
  • 空间复杂度:O(log n)

    • 最坏情况下,哈希表需要存储 O (log n) 个不同的数字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值