【每天学习一点算法 2026/04/07】快乐数

每天学习一点算法 2026/04/07

题目:快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。

然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。

如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

首先我们要明确,对一个数反复计算各位数字的平方和只有存在两个情况:

  1. 收敛到 1
  2. 进入一个固定的循环

假设是一个 m 位的数 ,每一位最大数只能是 9

那最大的计算结果就是 9 * 9 * m = 81m

然而这个数至少是 10m - 1 次方,当 m > 3 时,这个数本身是远远大于它每个位置上的数字的平方和的

所以我们知道一直重复计算一定不是发散的,一旦有了边界那么出现的数就是有限的,所以一直计算一定会进入循环 或者 收敛到 1(1 计算完还是 1 其实也是一种循环)。

于是我们只需要不断的计算直到遇到重复的数 或者 1

typescript 复制代码
function isHappy(n: number): boolean {
  const set = new Set()
  function helper(num: number) {
    if (set.has(num)) {
      return false
    }
    if (num === 1) {
      return true
    }
    set.add(num)
    const next = num.toString().split('').reduce((prev: number, current: string) => {
      return prev + Number(current) * Number(current)
    }, 0)
    return helper(next)
  }

  return helper(n)
};

既然是判断是否循环,其实我们还可以想到快慢指针的方法(龟兔赛跑),快指针每次计算两次,如果是快乐数快指针一定会先计算到 1,如果不是快乐数两个指针一定会相遇。

typescript 复制代码
function isHappy(n: number): boolean {
  function helper(n: number) {
    let totalSum = 0
    while (n > 0) {
      let d = n % 10
      n = Math.floor(n / 10)
      totalSum += d * d
    }
    return totalSum
  }
  let fast = n, slow = n
  fast = helper(fast)
  while (fast != slow && fast != 1) {
    // 快指针每次计算两次
    fast = helper(fast)
    fast = helper(fast)
    slow = helper(slow)
  }

  return fast === 1
};

题目来源:力扣(LeetCode)

相关推荐
星幻元宇VR14 分钟前
VR航空航天科普设备【VR时空直升机】
科技·学习·安全·生活·vr
_李小白21 分钟前
【android opencv学习笔记】Day 2: Mat类(图片数据结构体)
android·opencv·学习
智者知已应修善业1 小时前
【51单片机按键调节占空比3位数码管显示】2023-8-24
c++·经验分享·笔记·算法·51单片机
harder3211 小时前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
.5481 小时前
## Sorting(排序算法)
python·算法·排序算法
wuweijianlove2 小时前
算法的平均复杂度建模与性能回归分析的技术7
算法·数据挖掘·回归
子琦啊2 小时前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法
程序猿乐锅2 小时前
【Tilas|第三篇】多表SQL语句
数据库·经验分享·笔记·学习·mysql
徐某人..2 小时前
基于i.MX6ULL平台的智能网关系统开发
arm开发·c++·单片机·qt·物联网·学习·arm
AOwhisky3 小时前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes