2037. Minimum Number of Moves to Seat Everyone
Problem Description
You have n
available seats and n
students standing in a room. Each seat has a specific position given in the array seats
where seats[i]
represents the position of the i-th
seat. Similarly, each student has a starting position given in the array students
where students[j]
represents the position of the j-th
student.
You can move students to assign them to seats. In each move, you can:
- Move any student one position to the left or right (from position
x
tox+1
orx-1
)
Your goal is to assign each student to a seat such that:
- Every student sits in exactly one seat
- No two students share the same seat
- The total number of moves is minimized
The problem asks you to return the minimum total number of moves required to achieve this arrangement.
Important Notes:
- Multiple seats can initially be at the same position
- Multiple students can initially be at the same position
- Since there are exactly
n
seats andn
students, a valid assignment is always possible
Example:
If seats = [3, 1, 5]
and students = [2, 7, 4]
:
- After sorting:
seats = [1, 3, 5]
andstudents = [2, 4, 7]
- Optimal assignment: student at position 2 โ seat at position 1 (1 move), student at position 4 โ seat at position 3 (1 move), student at position 7 โ seat at position 5 (2 moves)
- Total moves =
|2-1| + |4-3| + |7-5| = 1 + 1 + 2 = 4
Intuition
The key insight is to think about this as a matching problem where we want to pair students with seats to minimize the total distance traveled.
Consider what happens if we have students at positions [2, 7, 4]
and seats at positions [3, 1, 5]
. We need to decide which student should go to which seat.
If we assign randomly, we might get a suboptimal result. For example, if the student at position 2 goes to seat at position 5, and the student at position 7 goes to seat at position 1, we'd have large distances to cover.
The optimal strategy is to match students and seats based on their relative ordering. Think of it this way: if we line up all students from left to right by their positions, and do the same for seats, then the leftmost student should go to the leftmost seat, the second-leftmost student to the second-leftmost seat, and so on.
Why does this work? If we tried to "cross" assignments (having a student on the left go to a seat on the right while a student on the right goes to a seat on the left), the paths would intersect, creating unnecessary extra distance. By maintaining the relative order, we avoid these inefficient crossings.
Mathematically, after sorting both arrays, the optimal assignment pairs students[i]
with seats[i]
for all i
. The total minimum moves is then:
sum(|students[i] - seats[i]|)
for all i
from 0
to n-1
.
This greedy approach works because each student-seat pairing is independent once we've determined the optimal matching order through sorting.
Solution Approach
The solution implements the greedy matching strategy we identified through sorting both arrays and pairing them in order.
Step-by-step implementation:
- Sort both arrays:
seats.sort()
- arranges seats in ascending order by positionstudents.sort()
- arranges students in ascending order by position
- Calculate total moves:
- Use
zip(seats, students)
to pair up the sorted arrays element by element - For each pair
(a, b)
wherea
is a seat position andb
is a student position, calculate the distance|a - b|
- Sum all these distances using
sum(abs(a - b) for a, b in zip(seats, students))
- Use
Why this works:
After sorting, we have:
- Seats ordered:
seat[0] โค seat[1] โค ... โค seat[n-1]
- Students ordered:
student[0] โค student[1] โค ... โค student[n-1]
The algorithm assigns:
- The leftmost student โ the leftmost seat
- The second leftmost student โ the second leftmost seat
- And so on...
This ensures no "crossing" of paths which would increase the total distance unnecessarily.
Time Complexity: O(n log n)
due to sorting both arrays
Space Complexity: O(1)
if we don't count the space used by sorting (typically O(log n)
for the sorting algorithm's recursion stack)
The elegance of this solution lies in recognizing that sorting transforms the problem from a complex assignment problem into a simple pairing problem where we just match elements at the same indices.
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 walk through a small example with seats = [4, 1, 5, 9]
and students = [1, 3, 2, 6]
.
Step 1: Sort both arrays
- Sorted seats:
[1, 4, 5, 9]
- Sorted students:
[1, 2, 3, 6]
Step 2: Pair up elements at the same indices
After sorting, we match:
- Student at position 1 โ Seat at position 1
- Student at position 2 โ Seat at position 4
- Student at position 3 โ Seat at position 5
- Student at position 6 โ Seat at position 9
Step 3: Calculate moves for each pairing
- Pairing 1:
|1 - 1| = 0
moves - Pairing 2:
|2 - 4| = 2
moves - Pairing 3:
|3 - 5| = 2
moves - Pairing 4:
|6 - 9| = 3
moves
Step 4: Sum up total moves
Total = 0 + 2 + 2 + 3 = 7
moves
Why this is optimal:
Consider if we tried a different assignment, like having the student at position 6 go to seat at position 1 instead. This would require 5 moves just for that one student, plus we'd need to reassign the student at position 1 elsewhere. Any "crossing" of assignments where a leftward student goes to a rightward seat (and vice versa) creates inefficiency.
By maintaining the relative order through sorting and pairing, we ensure each student travels the minimum necessary distance to reach an available seat without creating conflicts or unnecessary detours.
Solution Implementation
1class Solution:
2 def minMovesToSeat(self, seats: List[int], students: List[int]) -> int:
3 """
4 Calculate the minimum number of moves required to seat all students.
5 Each move consists of a student moving from one position to another.
6
7 Args:
8 seats: List of integers representing seat positions
9 students: List of integers representing student positions
10
11 Returns:
12 Integer representing the minimum total moves needed
13 """
14 # Sort both arrays to match closest seats with closest students
15 # This greedy approach ensures minimum total distance
16 seats.sort()
17 students.sort()
18
19 # Calculate total moves by summing absolute differences
20 # between corresponding positions after sorting
21 total_moves = sum(abs(seat - student) for seat, student in zip(seats, students))
22
23 return total_moves
24
1class Solution {
2 /**
3 * Calculates the minimum number of moves required to seat all students.
4 * Each student must be assigned to exactly one seat, and each move represents
5 * moving a student one position left or right.
6 *
7 * @param seats Array representing the positions of available seats
8 * @param students Array representing the current positions of students
9 * @return The minimum total number of moves required to seat all students
10 */
11 public int minMovesToSeat(int[] seats, int[] students) {
12 // Sort both arrays to match students with seats optimally
13 // Pairing the smallest position student with the smallest position seat
14 // minimizes the total distance
15 Arrays.sort(seats);
16 Arrays.sort(students);
17
18 // Initialize the total moves counter
19 int totalMoves = 0;
20
21 // Calculate the sum of distances between each student and their assigned seat
22 for (int i = 0; i < seats.length; i++) {
23 // Add the absolute distance between student i and seat i
24 totalMoves += Math.abs(seats[i] - students[i]);
25 }
26
27 return totalMoves;
28 }
29}
30
1class Solution {
2public:
3 int minMovesToSeat(vector<int>& seats, vector<int>& students) {
4 // Sort both arrays to optimally match students with seats
5 // After sorting, pairing seats[i] with students[i] minimizes total moves
6 sort(seats.begin(), seats.end());
7 sort(students.begin(), students.end());
8
9 // Calculate total moves needed
10 int totalMoves = 0;
11
12 // Pair each student with corresponding seat at same index
13 for (int i = 0; i < seats.size(); ++i) {
14 // Add absolute difference between seat position and student position
15 totalMoves += abs(seats[i] - students[i]);
16 }
17
18 return totalMoves;
19 }
20};
21
1/**
2 * Calculates the minimum number of moves required to seat all students
3 * @param seats - Array of seat positions
4 * @param students - Array of student positions
5 * @returns The minimum total number of moves needed
6 */
7function minMovesToSeat(seats: number[], students: number[]): number {
8 // Sort both arrays in ascending order to match closest seats with students
9 seats.sort((a: number, b: number) => a - b);
10 students.sort((a: number, b: number) => a - b);
11
12 // Calculate the total distance by summing up the absolute differences
13 // between each student's position and their assigned seat
14 const totalMoves: number = seats.reduce(
15 (accumulator: number, currentSeat: number, index: number) => {
16 // Add the distance between current seat and corresponding student
17 return accumulator + Math.abs(currentSeat - students[index]);
18 },
19 0
20 );
21
22 return totalMoves;
23}
24
Time and Space Complexity
The time complexity is O(n ร log n)
, where n
is the length of the arrays seats
and students
. This is because:
- Sorting the
seats
array takesO(n ร log n)
time - Sorting the
students
array takesO(n ร log n)
time - The
zip
andsum
operations with the list comprehension takeO(n)
time to iterate through both arrays once - Overall:
O(n ร log n) + O(n ร log n) + O(n) = O(n ร log n)
The space complexity is O(log n)
. This is because:
- Python's built-in
sort()
method uses Timsort algorithm, which requiresO(log n)
space for the recursion stack in the worst case - The
zip
operation and generator expression in thesum
function useO(1)
additional space since they don't create intermediate lists - Overall:
O(log n) + O(1) = O(log n)
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Attempting to Optimize Individual Assignments Without Sorting
A common mistake is trying to greedily match each student to their nearest available seat without first sorting both arrays. This approach seems intuitive but leads to suboptimal solutions.
Why this fails:
Consider seats = [1, 4, 2]
and students = [5, 2, 3]
- If we greedily assign student at position 5 to the nearest seat (4), we get: 5โ4 (1 move)
- Then student at position 2 might go to seat 2: 2โ2 (0 moves)
- Finally student at position 3 goes to remaining seat 1: 3โ1 (2 moves)
- Total: 3 moves
But the optimal solution after sorting gives us 2 moves total.
Solution: Always sort both arrays first before making assignments.
2. Modifying Input Arrays Without Considering Side Effects
The solution sorts the input arrays in-place using .sort()
. If the caller expects the original arrays to remain unchanged, this could cause bugs.
Solution: Create copies if needed:
seats_sorted = sorted(seats)
students_sorted = sorted(students)
3. Assuming Positions Are Unique
The problem explicitly states that multiple seats/students can start at the same position. Some might incorrectly assume unique positions and try to use set operations or dictionaries for matching.
Why this fails:
If seats = [1, 1, 3]
and students = [1, 2, 2]
, using sets would lose duplicates and make correct assignment impossible.
Solution: Maintain all duplicate positions by using lists and sorting, not sets.
4. Over-complicating with Assignment Algorithms
Some might recognize this as a bipartite matching problem and try to implement complex algorithms like the Hungarian algorithm or use dynamic programming.
Why this is unnecessary: While these approaches work, they have higher time complexity (O(nยณ) for Hungarian algorithm) compared to the simple O(n log n) sorting solution.
Solution: Recognize that when quantities are equal (n seats for n students), sorting naturally provides the optimal pairing.
Which of the tree traversal order can be used to obtain elements in a binary search tree in sorted order?
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
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
Want a Structured Path to Master System Design Too? Donโt Miss This!