Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Build confidence with an intuition-first walkthrough focused on array fundamentals.
There are n friends that are playing a game. The friends are sitting in a circle and are numbered from 1 to n in clockwise order. More formally, moving clockwise from the ith friend brings you to the (i+1)th friend for 1 <= i < n, and moving clockwise from the nth friend brings you to the 1st friend.
The rules of the game are as follows:
1st friend receives the ball.
1st friend passes it to the friend who is k steps away from them in the clockwise direction.2 * k steps away from them in the clockwise direction.3 * k steps away from them in the clockwise direction, and so on and so forth.In other words, on the ith turn, the friend holding the ball should pass it to the friend who is i * k steps away from them in the clockwise direction.
The game is finished when some friend receives the ball for the second time.
The losers of the game are friends who did not receive the ball in the entire game.
Given the number of friends, n, and an integer k, return the array answer, which contains the losers of the game in the ascending order.
Example 1:
Input: n = 5, k = 2 Output: [4,5] Explanation: The game goes as follows: 1) Start at 1st friend and pass the ball to the friend who is 2 steps away from them - 3rd friend. 2) 3rd friend passes the ball to the friend who is 4 steps away from them - 2nd friend. 3) 2nd friend passes the ball to the friend who is 6 steps away from them - 3rd friend. 4) The game ends as 3rd friend receives the ball for the second time.
Example 2:
Input: n = 4, k = 4 Output: [2,3,4] Explanation: The game goes as follows: 1) Start at the 1st friend and pass the ball to the friend who is 4 steps away from them - 1st friend. 2) The game ends as 1st friend receives the ball for the second time.
Constraints:
1 <= k <= n <= 50Problem summary: There are n friends that are playing a game. The friends are sitting in a circle and are numbered from 1 to n in clockwise order. More formally, moving clockwise from the ith friend brings you to the (i+1)th friend for 1 <= i < n, and moving clockwise from the nth friend brings you to the 1st friend. The rules of the game are as follows: 1st friend receives the ball. After that, 1st friend passes it to the friend who is k steps away from them in the clockwise direction. After that, the friend who receives the ball should pass it to the friend who is 2 * k steps away from them in the clockwise direction. After that, the friend who receives the ball should pass it to the friend who is 3 * k steps away from them in the clockwise direction, and so on and so forth. In other words, on the ith turn, the friend holding the ball should pass it to the friend who is i * k steps away from them in
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map
5 2
4 4
find-the-child-who-has-the-ball-after-k-seconds)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2682: Find the Losers of the Circular Game
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;
}
}
// Accepted solution for LeetCode #2682: Find the Losers of the Circular Game
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
}
# Accepted solution for LeetCode #2682: Find the Losers of the Circular Game
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]]
// Accepted solution for LeetCode #2682: Find the Losers of the Circular Game
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
}
}
// Accepted solution for LeetCode #2682: Find the Losers of the Circular Game
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;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.