2582. Pass the Pillow
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 linetime
: 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
.
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:
- The current position of the pillow holder
- The direction the pillow is moving (forward towards
n
or backward towards1
)
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 positionn
), 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:
-
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)
-
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
- Move the pillow:
- Loop
-
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! Setk = -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 EvaluatorExample 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
andans ≠ 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
andans ≠ 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.
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
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!