返回介绍

solution / 2600-2699 / 2682.Find the Losers of the Circular Game / README

发布于 2024-06-17 01:03:01 字数 4540 浏览 0 评论 0 收藏 0

2682. 找出转圈游戏输家

English Version

题目描述

n 个朋友在玩游戏。这些朋友坐成一个圈,按 顺时针方向1n 编号。准确的说,从第 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

解法

方法一:模拟

我们用一个数组 vis 记录每个朋友是否接到过球,初始时所有朋友都没有接到过球。然后我们按照题目描述的规则模拟游戏的过程,直到某个朋友第二次接到球为止。

在模拟过程中,我们用两个变量 $i$ 和 $p$ 分别表示当前持球的朋友编号和当前传球的步长。初始时 $i=0,p=1$,表示第一个朋友接到球。每次传球时,我们将 $i$ 更新为 $(i+p \times k) \bmod n$,表示下一个接球的朋友编号,然后将 $p$ 更新为 $p+1$,表示下一次传球的步长。当某个朋友第二次接到球时,游戏结束。

最后我们遍历数组 vis,将没有接到过球的朋友编号加入答案数组中即可。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是朋友的数量。

class Solution:
  def circularGameLosers(self, n: int, k: int) -> List[int]:
    vis = [False] * n
    i, p = 0, 1
    while not vis[i]:
      vis[i] = True
      i = (i + p * k) % n
      p += 1
    return [i + 1 for i in range(n) if not vis[i]]
class Solution {
  public int[] circularGameLosers(int n, int k) {
    boolean[] vis = new boolean[n];
    int cnt = 0;
    for (int i = 0, p = 1; !vis[i]; ++p) {
      vis[i] = true;
      ++cnt;
      i = (i + p * k) % n;
    }
    int[] ans = new int[n - cnt];
    for (int i = 0, j = 0; i < n; ++i) {
      if (!vis[i]) {
        ans[j++] = i + 1;
      }
    }
    return ans;
  }
}
class Solution {
public:
  vector<int> circularGameLosers(int n, int k) {
    bool vis[n];
    memset(vis, false, sizeof(vis));
    for (int i = 0, p = 1; !vis[i]; ++p) {
      vis[i] = true;
      i = (i + p * k) % n;
    }
    vector<int> ans;
    for (int i = 0; i < n; ++i) {
      if (!vis[i]) {
        ans.push_back(i + 1);
      }
    }
    return ans;
  }
};
func circularGameLosers(n int, k int) (ans []int) {
  vis := make([]bool, n)
  for i, p := 0, 1; !vis[i]; p++ {
    vis[i] = true
    i = (i + p*k) % n
  }
  for i, x := range vis {
    if !x {
      ans = append(ans, i+1)
    }
  }
  return
}
function circularGameLosers(n: number, k: number): number[] {
  const vis = new Array(n).fill(false);
  const ans: number[] = [];
  for (let i = 0, p = 1; !vis[i]; p++) {
    vis[i] = true;
    i = (i + p * k) % n;
  }
  for (let i = 0; i < vis.length; i++) {
    if (!vis[i]) {
      ans.push(i + 1);
    }
  }
  return ans;
}
impl Solution {
  pub fn circular_game_losers(n: i32, k: i32) -> Vec<i32> {
    let mut vis: Vec<bool> = vec![false; n as usize];

    let mut i = 0;
    let mut p = 1;
    while !vis[i] {
      vis[i] = true;
      i = (i + p * (k as usize)) % (n as usize);
      p += 1;
    }

    let mut ans = Vec::new();
    for i in 0..vis.len() {
      if !vis[i] {
        ans.push((i + 1) as i32);
      }
    }

    ans
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文