2682. 找出转圈游戏输家

61 阅读2分钟

题目

n 个朋友在玩游戏。这些朋友坐成一个圈,按 顺时针方向 从 1 到 n 编号。从第 i 个朋友的位置开始顺时针移动 1 步会到达第 (i + 1) 个朋友的位置(1 <= i < n),而从第 n 个朋友的位置开始顺时针移动 1 步会回到第 1 个朋友的位置。

游戏规则如下:

第 1 个朋友接球。

  • 接着,第 1 个朋友将球传给距离他顺时针方向 k 步的朋友。
  • 然后,接球的朋友应该把球传给距离他顺时针方向 2 * k 步的朋友。
  • 接着,接球的朋友应该把球传给距离他顺时针方向 3 * k 步的朋友,以此类推。

换句话说,在第 i 轮中持有球的那位朋友需要将球传递给距离他顺时针方向 i * k 步的朋友。

当某个朋友第 2 次接到球时,游戏结束。

在整场游戏中没有接到过球的朋友是 输家 。

给你参与游戏的朋友数量 n 和一个整数 k ,请按升序排列返回包含所有输家编号的数组 answer 作为答案。

 

示例 1:

输入: n = 5, k = 2
输出: [4,5]
解释: 以下为游戏进行情况:
1)第 1 个朋友接球,第 1 个朋友将球传给距离他顺时针方向 2 步的玩家 —— 第 3 个朋友。
2)第 3 个朋友将球传给距离他顺时针方向 4 步的玩家 —— 第 2 个朋友。
3)第 2 个朋友将球传给距离他顺时针方向 6 步的玩家 —— 第 3 个朋友。
4)第 3 个朋友接到两次球,游戏结束。

示例 2:

输入: n = 4, k = 4
输出: [2,3,4]
解释: 以下为游戏进行情况:
1)第 1 个朋友接球,第 1 个朋友将球传给距离他顺时针方向 4 步的玩家 —— 第 1 个朋友。
2)第 1 个朋友接到两次球,游戏结束。

 

提示:

  • 1 <= k <= n <= 50

题解

由题可知,总共由n个位置,起始编号为1, 第i个朋友的位置顺时针移动1步会达到第(i+1) % n + 1的位置。

为了计算方便,设第 1个小朋友的起始位置为0, 则从0开始传递,同时用visit数组来标记每个位置是否被访问过, 如果当前的位置为j, 则第i次传递后球的位置处于(j + i * k) % n, 此时将所有访问过的位置标记即可,直到当前位置j已经被遍历则直接结束,然后依次遍历找到未被访问的位置返回即可。

代码

/**
 * @param {number} n
 * @param {number} k
 * @return {number[]}
 */
var circularGameLosers = function(n, k) {
    let visit = new Array(n).fill(false);
    for (let i = k, j = 0; !visit[j]; i += k) {
        visit[j] = true;
        j = (j + i) % n;
    }

    let res = [];
    for (let i = 0; i < n; i++) {
        if (!visit[i]) {
            res.push(i+1)
        }
    }
    
    return res;
};