递枕头

191 阅读2分钟

🎈 算法并不一定都是很难的题目,也有很多只是一些代码技巧,多进行一些算法题目的练习,可以帮助我们开阔解题思路,提升我们的逻辑思维能力,也可以将一些算法思维结合到业务代码的编写思考中。简而言之,平时进行的算法习题练习带给我们的好处一定是不少的,所以让我们一起来养成算法练习的习惯。今天练习的题目是一道比较简单的题目 ->递枕头

问题描述

n 个人站成一排,按从 1 到 n 编号。

最初,排在队首的第一个人拿着一个枕头。每秒钟,拿着枕头的人会将枕头传递给队伍中的下一个人。一旦枕头到达队首或队尾,传递方向就会改变,队伍会继续沿相反方向传递枕头。

  • 例如,当枕头到达第 n 个人时,TA 会将枕头传递给第 n - 1 个人,然后传递给第 n - 2 个人,依此类推。

给你两个正整数 n 和 time ,返回 time 秒后拿着枕头的人的编号。

示例 1:

输入: n = 4, time = 5
输出: 2
解释: 队伍中枕头的传递情况为:1 -> 2 -> 3 -> 4 -> 3 -> 25 秒后,枕头传递到第 2 个人手中。

示例 2:

输入: n = 3, time = 2
输出: 3
解释: 队伍中枕头的传递情况为:1 -> 2 -> 3 。
2 秒后,枕头传递到第 3 个人手中。

提示:

  • 2 <= n <= 1000
  • 1 <= time <= 1000

思路分析

首先我们应该要先理解一下题目意思,题目会给我们一个整数n,代表有n个人,编号为1 ~ n;一个整数time,代表需要将枕头传递time次,每次传递到头或尾时需要转变方向继续传递。

首先我们先计算一下将枕头传递完整一遍需要的次数为多少,如下图,有5个人的情况下,将枕头从头传递到尾我们需要传递4次,那么有n个人的话,我们将枕头从头传递到尾我们则需要传递n - 1次。

image.png

  • 计算枕头会传递几轮

我们可以先计算枕头会完整地传递几轮,通过轮数判断最后枕头传递方向是从前往后还是从后往前。第一轮为从前往后,第二轮为从后往前,所以我们可以知道如果是偶数轮数的话,那么其下一轮就是从前往后传递,反之则是从后往前传递。

const turn = Math.floor(time / (n - 1));
  • 计算最后不够一轮的传递次数

直接使用总传递次数对每轮传递次数求余即可。

const m = time % (n - 1);
  • 计算最后枕头所在位置

如果当前枕头传递方向是从前往后时,那么枕头所在位置即为不足一轮传递次数 + 1,这里为什么要加一呢?因为编号是从1开始,如果传递次数为0的话,枕头应该是在1号手上;如果当前枕头传递方向是从后往前时,那么我们直接用总人数减m就可以。

if (turn % 2 === 1) return n - m;
return (m + 1) % n;

AC 代码

完整 AC 代码如下:

/**
 * @param {number} n
 * @param {number} time
 * @return {number}
 */
var passThePillow = function (n, time) {
  const turn = Math.floor(time / (n - 1));
  const m = time % (n - 1);
  if (turn % 2 === 1) return n - m;
  return (m + 1) % n;
};

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,在此谢谢大家的支持,我们下文再见 🙌。