Minimum Number of Moves to Seat Everyone
Easy · Greedy · Explanation and code example
Counting Sort (Optimal)
How it works
When multiple students are at the same position or multiple seats are at the same position, we can batch process them. Instead of matching one pair at a time, we match min(count_seats[i], count_students[j]) pairs at once, multiplying the distance by the batch size.
This optimization reduces iterations when there are many duplicates, though the asymptotic complexity remains the same.
Steps
- Create count arrays for seats and students.
- Use two pointers
iandjstarting at position 0. - While unmatched pairs remain:
- Advance
iuntilcount_seats[i] > 0. - Advance
juntilcount_students[j] > 0. - Compute
tmp = min(count_seats[i], count_students[j]). - Add
|i - j| * tmptores, decrement counts bytmp.
- Advance
- Return the total.
Complexity
- Time complexity:
O(n + m1 + m2) - Space complexity:
O(m1 + m2)
Where
nis the size of the input arrays,m1is the maximum value in the arrayseats, andm2is the maximum value in the arraystudents.
Things to watch for
Not Sorting Both Arrays
The greedy solution requires sorting both the seats and students arrays before pairing. Sorting only one array or forgetting to sort altogether will produce incorrect results. The optimal pairing matches the i-th smallest student with the i-th smallest seat, which requires both arrays to be in sorted order.
Using Signed Subtraction Instead of Absolute Difference
When calculating the distance between a seat and a student, you must use abs(seats[i] - students[i]), not just seats[i] - students[i]. If a student is at a larger position than their assigned seat, the subtraction would be negative, leading to an incorrect (and possibly negative) total. Always use the absolute value to measure distance.
Python code example
from typing import List
class Solution:
def minMovesToSeat(self, seats: List[int], students: List[int]) -> int:
count_seats = [0] * (max(seats) + 1)
count_students = [0] * (max(students) + 1)
def count_sort(arr, count):
for num in arr:
count[num] += 1
count_sort(seats, count_seats)
count_sort(students, count_students)
remain = len(seats)
i = j = res = 0
while remain:
if count_seats[i] == 0:
i += 1
if count_students[j] == 0:
j += 1
if count_seats[i] and count_students[j]:
tmp = min(count_seats[i], count_students[j])
res += abs(i - j) * tmp
count_seats[i] -= tmp
count_students[j] -= tmp
remain -= tmp
return res
C++ code example
class Solution {
public:
int minMovesToSeat(vector<int>& seats, vector<int>& students) {
int maxSeat = *max_element(seats.begin(), seats.end());
int maxStudent = *max_element(students.begin(), students.end());
vector<int> count_seats(maxSeat + 1, 0);
vector<int> count_students(maxStudent + 1, 0);
for (int s : seats) count_seats[s]++;
for (int s : students) count_students[s]++;
int remain = seats.size(), i = 0, j = 0, res = 0;
while (remain > 0) {
if (count_seats[i] == 0) {
i++;
continue;
}
if (count_students[j] == 0) {
j++;
continue;
}
int tmp = min(count_seats[i], count_students[j]);
res += abs(i - j) * tmp;
count_seats[i] -= tmp;
count_students[j] -= tmp;
remain -= tmp;
}
return res;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.