Facebook Pixel

2582. Pass the Pillow

EasyMathSimulation
Leetcode Link

Problem Description

You have n people standing in a line, numbered from 1 to n. Person 1 starts with a pillow and passes it to the next person every second. When the pillow reaches person n (the last person), the direction reverses - person n passes it back to person n-1, then to person n-2, and so on. When the pillow reaches person 1 again, the direction reverses once more, and the pattern continues.

The pillow moves like a bouncing ball between the two ends of the line:

  • Starting at person 1, it moves forward: 1 → 2 → 3 → ... → n
  • Upon reaching person n, it bounces back: n → n-1 → n-2 → ... → 1
  • Upon reaching person 1, it bounces forward again, and this pattern repeats

Given two positive integers:

  • n: the number of people in the line
  • time: the number of seconds that have passed

You need to find which person (by their position number) is holding the pillow after exactly time seconds.

For example, if n = 4 and time = 5:

  • At time 0: Person 1 has the pillow
  • At time 1: Person 2 has the pillow
  • At time 2: Person 3 has the pillow
  • At time 3: Person 4 has the pillow (reaches the end, direction reverses)
  • At time 4: Person 3 has the pillow
  • At time 5: Person 2 has the pillow

The answer would be 2.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key observation is that the pillow moves in a predictable pattern - it bounces back and forth between position 1 and position n. We can think of this as a person walking along a line, taking one step each second, and turning around whenever they reach either end.

To track this movement, we need two pieces of information:

  1. The current position of the pillow holder
  2. The direction the pillow is moving (forward towards n or backward towards 1)

We can simulate this step-by-step process:

  • Start at position 1 with the pillow moving forward (direction = +1)
  • For each second that passes, move one position in the current direction
  • Whenever we reach an endpoint (position 1 or position n), we reverse the direction

The direction can be represented as a variable k that is either +1 (moving forward) or -1 (moving backward). When we hit a boundary, we simply multiply k by -1 to flip the direction.

For example, if we're at position n and moving forward (k = 1), we've hit the right boundary. We change k to -1, so the next move will be n + (-1) = n - 1, moving backward.

By simulating exactly time steps of this process, we can determine the final position of the pillow. The simulation directly mirrors the physical process described in the problem, making it an intuitive and straightforward approach.

Learn more about Math patterns.

Solution Approach

The simulation approach implements the intuition directly by tracking the pillow's position and direction through each second.

Implementation Steps:

  1. Initialize variables:

    • ans = 1: The current position of the pillow holder (starts at person 1)
    • k = 1: The direction of movement (+1 for forward, -1 for backward)
  2. Simulate each second:

    • Loop time times to simulate each passing second
    • In each iteration:
      • Move the pillow: ans += k (add the direction to current position)
      • Check if we've hit a boundary: if ans == 1 or ans == n
      • If at a boundary, reverse direction: k *= -1
  3. Return the final position after all time seconds have passed

Why the boundary check happens after moving: Notice that we update the position first (ans += k) and then check for boundaries. This is because:

  • When we reach position n moving forward, the next move should be backward
  • When we reach position 1 moving backward, the next move should be forward
  • The direction change takes effect for the next move, not the current one

Example walkthrough with n = 4, time = 5:

  • Start: ans = 1, k = 1
  • Second 1: ans = 1 + 1 = 2, no boundary hit
  • Second 2: ans = 2 + 1 = 3, no boundary hit
  • Second 3: ans = 3 + 1 = 4, boundary hit! Set k = -1
  • Second 4: ans = 4 + (-1) = 3, no boundary hit
  • Second 5: ans = 3 + (-1) = 2, no boundary hit
  • Return: 2

The time complexity is O(time) since we iterate exactly time times, and the space complexity is O(1) as we only use a constant amount of extra space.

Ready to land your dream job?

Unlock your dream job with a 3-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's trace through the solution with n = 3 people and time = 4 seconds.

Initial Setup:

  • ans = 1 (pillow starts at person 1)
  • k = 1 (moving forward towards person n)

Simulation:

Second 1:

  • Move pillow: ans = ans + k = 1 + 1 = 2
  • Check boundaries: ans ≠ 1 and ans ≠ 3, no boundary hit
  • State: Person 2 has the pillow, still moving forward

Second 2:

  • Move pillow: ans = ans + k = 2 + 1 = 3
  • Check boundaries: ans = 3 (hit right boundary!)
  • Reverse direction: k = k × (-1) = -1
  • State: Person 3 has the pillow, will move backward next

Second 3:

  • Move pillow: ans = ans + k = 3 + (-1) = 2
  • Check boundaries: ans ≠ 1 and ans ≠ 3, no boundary hit
  • State: Person 2 has the pillow, moving backward

Second 4:

  • Move pillow: ans = ans + k = 2 + (-1) = 1
  • Check boundaries: ans = 1 (hit left boundary!)
  • Reverse direction: k = k × (-1) = 1
  • State: Person 1 has the pillow, will move forward next

Result: After 4 seconds, person 1 is holding the pillow.

The pillow's journey: 1 → 2 → 3 → 2 → 1

This demonstrates how the pillow bounces between the endpoints, with direction changes occurring exactly when we reach person 1 or person n.

Solution Implementation

1class Solution:
2    def passThePillow(self, n: int, time: int) -> int:
3        # Initialize current position at person 1 and direction as forward (+1)
4        current_position = 1
5        direction = 1
6      
7        # Simulate the pillow passing for 'time' seconds
8        for _ in range(time):
9            # Move the pillow to the next person in the current direction
10            current_position += direction
11          
12            # Check if we've reached either end of the line
13            if current_position == 1 or current_position == n:
14                # Reverse direction when reaching the ends
15                direction *= -1
16      
17        return current_position
18```
19
20Alternative optimized solution without simulation:
21
22```python3
23class Solution:
24    def passThePillow(self, n: int, time: int) -> int:
25        # Each complete cycle takes (n-1) * 2 time units
26        # (n-1) to go from 1 to n, and (n-1) to go back from n to 1
27        cycle_length = (n - 1) * 2
28      
29        # Find position within the current cycle
30        time_in_cycle = time % cycle_length
31      
32        # If we're in the forward pass (going from 1 to n)
33        if time_in_cycle <= n - 1:
34            return 1 + time_in_cycle
35        # Otherwise, we're in the backward pass (going from n to 1)
36        else:
37            return n - (time_in_cycle - (n - 1))
38
1class Solution {
2    public int passThePillow(int n, int time) {
3        // Initialize current position to 1 (first person)
4        int currentPosition = 1;
5      
6        // Direction of movement: 1 for forward, -1 for backward
7        int direction = 1;
8      
9        // Simulate the pillow passing for 'time' seconds
10        while (time-- > 0) {
11            // Move the pillow to the next position
12            currentPosition += direction;
13          
14            // Check if we've reached either end of the line
15            if (currentPosition == 1 || currentPosition == n) {
16                // Reverse direction when reaching the first or last person
17                direction *= -1;
18            }
19        }
20      
21        // Return the final position of the pillow
22        return currentPosition;
23    }
24}
25
1class Solution {
2public:
3    int passThePillow(int n, int time) {
4        // Initialize current position to 1 (first person)
5        int currentPosition = 1;
6      
7        // Direction of movement: 1 for forward, -1 for backward
8        int direction = 1;
9      
10        // Simulate the pillow passing for 'time' seconds
11        while (time--) {
12            // Move to the next position based on current direction
13            currentPosition += direction;
14          
15            // Check if we've reached either end of the line
16            if (currentPosition == 1 || currentPosition == n) {
17                // Reverse direction when reaching either end
18                direction *= -1;
19            }
20        }
21      
22        // Return the final position of the pillow
23        return currentPosition;
24    }
25};
26
1/**
2 * Simulates passing a pillow between n people in a line.
3 * The pillow starts at person 1 and moves one position at a time.
4 * When it reaches either end (person 1 or person n), it reverses direction.
5 * 
6 * @param n - The number of people in the line
7 * @param time - The number of seconds to pass the pillow
8 * @returns The position of the person holding the pillow after the given time
9 */
10function passThePillow(n: number, time: number): number {
11    // Current position of the pillow (starts at person 1)
12    let currentPosition: number = 1;
13  
14    // Direction of movement: 1 for forward (towards person n), -1 for backward (towards person 1)
15    let direction: number = 1;
16  
17    // Simulate each second of passing the pillow
18    while (time-- > 0) {
19        // Move the pillow in the current direction
20        currentPosition += direction;
21      
22        // Check if we've reached either end of the line
23        if (currentPosition === 1 || currentPosition === n) {
24            // Reverse direction when reaching the ends
25            direction *= -1;
26        }
27    }
28  
29    return currentPosition;
30}
31

Time and Space Complexity

The time complexity is O(time) because the code contains a single for loop that iterates exactly time times. In each iteration, the code performs constant-time operations: adding to ans, checking conditions with an if statement, and potentially multiplying k by -1. Since these operations are all O(1) and they are executed time times, the overall time complexity is O(time).

The space complexity is O(1) because the code only uses a fixed amount of extra space regardless of the input size. The variables ans and k are simple integers that do not scale with the input parameters n or time. No additional data structures like arrays, lists, or recursive call stacks are used, so the space usage remains constant.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Off-by-one error in boundary checking

A common mistake is checking boundaries before updating the position, or using incorrect boundary conditions:

Incorrect approach:

# Wrong: Checking boundary BEFORE moving
for _ in range(time):
    if current_position == 1 or current_position == n:
        direction *= -1
    current_position += direction  # This will overshoot!

This causes the pillow to go beyond the boundaries (position 0 or n+1) because the direction changes before the move is made.

Solution: Always update position first, then check if the new position is at a boundary:

for _ in range(time):
    current_position += direction
    if current_position == 1 or current_position == n:
        direction *= -1

2. Incorrect cycle length calculation in optimized solution

When calculating the cycle pattern, a frequent error is using n * 2 instead of (n - 1) * 2:

Incorrect:

cycle_length = n * 2  # Wrong!

Why it's wrong: The pillow takes n - 1 steps to go from position 1 to n (not n steps), and another n - 1 steps to return.

Solution: Use the correct formula:

cycle_length = (n - 1) * 2

3. Wrong initial direction assumption

Starting with direction = -1 or direction = 0:

Incorrect:

current_position = 1
direction = -1  # Wrong: pillow starts moving forward, not backward

Solution: Always initialize with direction = 1 since the pillow starts moving forward from person 1.

4. Mishandling edge case when time = 0

Some implementations might incorrectly handle the case where time = 0:

Incorrect:

# Processing the move before checking if time is 0
current_position = 1
direction = 1
current_position += direction  # Wrong: moved before checking time
for _ in range(time):
    # ...

Solution: The loop naturally handles time = 0 correctly by not executing any iterations, keeping the pillow at position 1.

Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

What is the best way of checking if an element exists in a sorted array once in terms of time complexity? Select the best that applies.


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More