Facebook Pixel

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 to x+1 or x-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 and n students, a valid assignment is always possible

Example: If seats = [3, 1, 5] and students = [2, 7, 4]:

  • After sorting: seats = [1, 3, 5] and students = [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
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

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.

Learn more about Greedy and Sorting patterns.

Solution Approach

The solution implements the greedy matching strategy we identified through sorting both arrays and pairing them in order.

Step-by-step implementation:

  1. Sort both arrays:
    • seats.sort() - arranges seats in ascending order by position
    • students.sort() - arranges students in ascending order by position
  2. Calculate total moves:
    • Use zip(seats, students) to pair up the sorted arrays element by element
    • For each pair (a, b) where a is a seat position and b 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))

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 Evaluator

Example 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 takes O(n ร— log n) time
  • Sorting the students array takes O(n ร— log n) time
  • The zip and sum operations with the list comprehension take O(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 requires O(log n) space for the recursion stack in the worst case
  • The zip operation and generator expression in the sum function use O(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.

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

Which of the tree traversal order can be used to obtain elements in a binary search tree in sorted order?


Recommended Readings

Want a Structured Path to Master System Design Too? Donโ€™t Miss This!

Load More