Card 08/ 09
Practice: Rotating a Row of Seats
Move the last k seats of a row to the front without a second array.
Rotating an array moves its last k elements to the front, and doing it inside the array, without a second one, practises index arithmetic and the cost of moving elements. This card covers it as an exercise, with an answer to check yours against.
A row of six theatre seats holds guests 1 2 3 4 5 6. The usher moves everyone k seats to the right, and guests pushed past the end wrap round to the start, so with k = 2 the row becomes 5 6 1 2 3 4. Using no second array:
- Say at which index the guest at index i ends up, for any k, including a k larger than the row.
- Write
rotate(seats, k)so that it rearranges the list in place. - State its time and its extra space, and compare them with moving everyone one seat to the right, k times over.
An answer: where each guest ends up, a rotate made of three reversals, and its cost
With n seats, the guest at index i ends up at (i + k) mod n, where mod is the remainder after division, written % in all three languages. Rotating six seats by 8 is the same as rotating them by 2, because 8 mod 6 = 2.
One way to rotate in place is to reverse the whole row, then the first k cells, then the rest. Each reversal swaps the two ends and moves inwards.
def reverse(seats: list[int], left: int, right: int) -> None:
while left < right:
seats[left], seats[right] = seats[right], seats[left]
left += 1
right -= 1
def rotate(seats: list[int], k: int) -> None:
n = len(seats)
if n == 0:
return
k = k % n
reverse(seats, 0, n - 1)
reverse(seats, 0, k - 1)
reverse(seats, k, n - 1)
for k in [2, 8, 0]:
seats = [1, 2, 3, 4, 5, 6]
rotate(seats, k)
print(f"k = {k}: {seats}")k = 2: [5, 6, 1, 2, 3, 4]
k = 8: [5, 6, 1, 2, 3, 4]
k = 0: [1, 2, 3, 4, 5, 6]The trace shows the three reversals for k = 2; left and right mark the ends of the range each reversal covers.
Inputseats = 1 2 3 4 5 6, k = 2
Start
- 1left
- 2
- 3
- 4
- 5
- 6right
Six seats, and k = 2, so seats 5 and 6 must reach the front.
Reverse cells 0 to 5
- 6left
- 5
- 4
- 3
- 2
- 1right
Reversing the whole row brings the last two to the front, backwards.
Reverse cells 0 to 1
- 5left
- 6right
- 4
- 3
- 2
- 1
Reversing the first k cells puts 5 and 6 back in order.
Reverse cells 2 to 5
- 5
- 6
- 1left
- 2
- 3
- 4right
Reversing the rest puts 1 to 4 back in order.
Result5 6 1 2 3 4, rearranged inside the one array.
The three reversals swap each seat at most twice, so the rotation is O(n) in time and O(1) in extra space. Moving everyone one seat right shifts n − 1 guests each time, and doing it k times is O(n · k), which becomes O(n²) when k is close to n.
← → move through sections and cards