likes
comments
collection
share

今天的你快乐了嘛-快慢指针法求快乐数

作者站长头像
站长
· 阅读数 28

前言

在 JavaScript 中,快慢指针法通常用于解决链表相关的问题,但也可以用于解决其他类型的问题,比如判断一个数是否为快乐数。

快慢指针法的基本思想是使用两个指针,一个移动速度比另一个快,从而在一个数据结构(比如链表)中实现一些特定操作。通常情况下,快指针每次移动两步,慢指针每次移动一步。通过这种方式,可以在单次遍历中找到链表的中间节点、判断链表是否有环等。

在判断一个数是否为快乐数的问题中,使用快慢指针的思想是为了检测循环。通过每次计算两次数字的平方和,快指针相当于走得更快,如果存在循环,快慢指针最终会相遇。如果最终快指针的值等于1,那么这个数是快乐数;如果快慢指针相遇但不等于1,那么这个数不是快乐数。

在 JavaScript 中,快慢指针法通常使用 while 循环实现,其中包含两个指针的移动逻辑以及判断是否相遇的逻辑。

LeetCode202

编写一个算法来判断一个数 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

解决方案概述

我们将使用JavaScript语言来解决这个问题。具体来说,我们将结合函数式编程和快慢指针算法。

函数式编程实现

首先,我们定义一个函数 num,用于计算一个数的每个位置上的数字的平方和。这个函数接收一个数作为参数,将其转换为字符串,然后拆分成数组,对每个元素进行平方运算,最后使用 reduce 方法求和。

let num = n => n.toString().split('').map(elem => elem * elem).reduce((prev, current) => prev + current);

快慢指针算法

接下来,我们使用快慢指针算法来判断一个数是否是快乐数。我们定义两个指针 slowfast,初始值都为给定的数 n。然后,我们在循环中,每次将 slow 移动一步,将 fast 移动两步,直到它们相遇,或者 fast 达到1。若 fast 最终等于1,则说明该数是快乐数。

let slow = n;
let fast = num(n);

while (fast !== 1 && fast !== slow) {
    slow = num(slow);
    fast = num(num(fast));
}

返回结果

最后,我们根据循环结束后 fast 的值来判断结果。如果 fast 不等于1,则该数不是快乐数,否则是快乐数。

if (fast !== 1) fast = false;
return fast;

代码

var isHappy = function(n) {
  // 定义一个内部函数 num,用于计算一个数的每个位置上的数字的平方和
  let num = n => n.toString().split('').map(elem => elem * elem).reduce((prev, current) => prev + current);
  
  // 初始化慢指针为n,快指针为num(n)
  let slow = n;
  let fast = num(n);
  
  // 使用快慢指针算法判断是否为快乐数
  while (fast !== 1 && fast !== slow) {
      slow = num(slow);
      fast = num(num(fast));
  }
  
  // 判断循环结束后的fast的值,如果不等于1,则该数不是快乐数
  if (fast !== 1) fast = false;
  
  // 返回结果
  return fast;
}

我们定义了一个函数 isHappy,其作用是判断一个整数是否为快乐数。快乐数的定义是:对于一个正整数,将其替换为各个位上的数字的平方和,重复这个过程直到结果为1,或者进入循环无法到达1。

  1. num 函数:这是一个内部函数,使用箭头函数的形式定义,接受一个参数 n。这个函数的作用是将传入的数字转换为字符串,然后使用 split('') 方法将其拆分为单个数字的数组,接着对每个数字进行平方操作,最后使用 reduce 方法求和。这样就得到了该数的每个位置上的数字的平方和。
  2. 初始化变量:代码中初始化了两个变量 slowfast,分别用于追踪快慢指针算法中的慢指针和快指针。slow 被赋值为输入的整数 n,而 fast 则被赋值为调用 num 函数后的结果,即 n 的各个位上数字的平方和。
  3. 快慢指针算法:代码使用了快慢指针算法来判断一个数是否为快乐数。在一个 while 循环中,不断更新 slowfast 的值,直到 fast 的值等于1或者 fastslow 的值相等。在每次循环中,slow 更新一次,而 fast 更新两次,这样可以在循环过程中判断是否存在循环。
  4. 判断循环结束后的 fast 值:如果循环结束后 fast 的值不等于1,那么将 fast 赋值为 false,表示输入的数不是快乐数。
  5. 返回结果:根据 fast 的值,返回 truefalse,表示输入的数是否为快乐数。
转载自:https://juejin.cn/post/7363159504832462884
评论
请登录