2037. Minimum Number of Moves to Seat Everyone


Problem Description

In this problem, we have n seats and n students, with each being given an initial position. The goal is to find the minimum number of moves required to place each student in a seat such that no two students end up in the same seat. The array seats contains the positions of the seats and the array students contains the initial positions of the students. A move consists of increasing or decreasing the position of a student by 1. This problem becomes a matter of optimally matching each student to a seat.

Intuition

The key to solving this problem is realizing that the most optimal way to match students to seats with the minimum moves is to match the closest available seat to each student. To achieve this, we can sort both the seats and students arrays. Sorting brings pairs of students and seats that are closest to each other in correspondence.

Once sorted, the position of the i-th student should match with the i-th seat. Since each move changes a position by 1, the total moves for each student to reach their seat is the absolute difference between their position and their allocated seat's position. By sorting, we ensure that we are not crossing pairs, which could potentially lead to a higher number of moves if we were to move students past each other.

When the pairs are matched one-to-one in a sorted manner, we can sum the absolute differences of corresponding pairs to find the minimum number of moves required for all students to be seated.

Learn more about Sorting patterns.

Not Sure What to Study? Take the 2-min Quiz to Find Your Missing Piece:

How would you design a stack which has a function min that returns the minimum element in the stack, in addition to push and pop? All push, pop, min should have running time O(1).

Solution Approach

The solution involves sorting algorithms and the concept of absolute difference to calculate the minimum number of moves. The following steps depict the implementation:

  1. Sorting: We use a sorting algorithm (such as quicksort, mergesort, etc., typically O(n log n) complexity) to sort both the seats and students arrays. In Python, this is done using the sort() method directly on the lists, which sorts the list in-place.

  2. Pairing Students with Seats: After sorting, the students and seats are paired up by their indices. That is, the first student (students[0]) will go to the first seat (seats[0]), and so on.

  3. Calculating Moves: Since the solution only requires the total number of moves, we go through each pair (student, seat) and calculate the absolute difference between their positions. The abs() function is used for this purpose, which is a built-in function in Python to calculate the absolute value of a number.

    For example, if a student is at position 2 (students[i] = 2) and their paired seat is at position 5 (seats[i] = 5), the moves required to get the student to that seat would be abs(2 - 5) = 3. The number of moves is then added to a running total.

  4. Summing Up Moves: As we calculate the absolute difference for each student and seat pair, we sum up these differences using the sum() function. This sum represents the total minimum number of moves required to seat all students. The zip() function in Python is helpful here to iterate over corresponding elements of seats and students simultaneously.

The code for this would look like this:

1class Solution:
2    def minMovesToSeat(self, seats: List[int], students: List[int]) -> int:
3        seats.sort()      # Sort the seats array.
4        students.sort()   # Sort the students array.
5        # Calculate the sum of absolute differences between paired students and seats.
6        return sum(abs(a - b) for a, b in zip(seats, students))

This approach guarantees an optimal solution with a time complexity of O(n log n) because of the sorting step, which is the most time-consuming part of the algorithm. The pairing and summing steps are linear, making it O(n). Therefore, the sorting step dictates the overall time complexity.

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

Which type of traversal does breadth first search do?

Example Walkthrough

Let's consider an example with n = 3 seats and n = 3 students with the following initial positions:

  • seats = [4, 1, 5]
  • students = [3, 2, 6]

First, using the solution approach, we need to sort both seats and students arrays to organize them in ascending order:

  • Sorted seats: [1, 4, 5]
  • Sorted students: [2, 3, 6]

Now, we pair the students with their seats by index:

  • 1st pair: seat at position 1 and student at position 2 (student needs to move 1 position to the left)
  • 2nd pair: seat at position 4 and student at position 3 (student needs to move 1 position to the right)
  • 3rd pair: seat at position 5 and student at position 6 (student needs to move 1 position to the left)

Next, we calculate the absolute differences for each pair to find out the number of moves required:

  • Moves for 1st pair: abs(seats[0] - students[0]) = abs(1 - 2) = 1
  • Moves for 2nd pair: abs(seats[1] - students[1]) = abs(4 - 3) = 1
  • Moves for 3rd pair: abs(seats[2] - students[2]) = abs(5 - 6) = 1

Finally, we sum up the number of moves for all pairs to find the total minimum number of moves:

  • Total moves: (1 + 1 + 1) = 3

Thus, it takes a minimum of 3 moves to seat all the students.

Solution Implementation

1class Solution:
2    def min_moves_to_seat(self, seats: List[int], students: List[int]) -> int:
3        # First, sort the lists of seats and students to organize them in ascending order.
4        # This aligns each student to the closest available seat.
5        seats.sort()
6        students.sort()
7      
8        # Next, calculate the total number of moves by iterating over the paired sorted lists.
9        # For each pair, find the absolute difference between a student's position and
10        # a seat's position. This represents the number of moves a student must make to reach the seat.
11        moves = sum(abs(seat - student) for seat, student in zip(seats, students))
12      
13        # Return the total number of moves needed for all students to sit in the seats.
14        return moves
15
1import java.util.Arrays; // Import Arrays class for sorting
2
3class Solution {
4    // Method to find the minimum number of moves required to seat all students.
5    // Each student moves to a seat, and the total moves should be minimized.
6    public int minMovesToSeat(int[] seats, int[] students) {
7        // Sort the arrays to match student-seat pairs by their order.
8        Arrays.sort(seats);
9        Arrays.sort(students);
10
11        // Initialize the count of moves to zero.
12        int totalMoves = 0;
13
14        // Iterate over the arrays to match each student to a seat
15        for (int i = 0; i < seats.length; ++i) {
16            // Add the absolute difference of positions to total moves.
17            // Absolute difference indicates the number of moves for each student.
18            totalMoves += Math.abs(seats[i] - students[i]);
19        }
20
21        // Return the total number of moves required to seat all students.
22        return totalMoves;
23    }
24}
25
1#include <vector> // Include header for vector
2#include <algorithm> // Include header for sort
3
4class Solution {
5public:
6    // Function to find the minimum number of moves to seat everyone
7    int minMovesToSeat(vector<int>& seats, vector<int>& students) {
8        // Sort the 'seats' vector in non-decreasing order.
9        sort(seats.begin(), seats.end());
10        // Sort the 'students' vector in non-decreasing order.
11        sort(students.begin(), students.end());
12      
13        // Initialize a variable 'minMoves' to store the minimum number of moves needed.
14        int minMoves = 0;
15        // Iterate over the sorted vectors to find the total moves needed.
16        for (int i = 0; i < seats.size(); ++i) {
17            // Calculate the absolute difference between corresponding seats and students
18            // and add it to the 'minMoves' counter.
19            minMoves += abs(seats[i] - students[i]);
20        }
21        // Return the total minimum number of moves required.
22        return minMoves;
23    }
24};
25
1// Function to calculate the minimum number of moves required to seat students.
2// Each student moves to their seat with the least possible amount of individual moves.
3// Parameters `seats` and `students` are arrays of numbers representing seat positions and students' current positions respectively.
4function minMovesToSeat(seats: number[], students: number[]): number {
5    // Sort the seats array in ascending order.
6    seats.sort((a, b) => a - b);
7    // Sort the students array in ascending order.
8    students.sort((a, b) => a - b);
9  
10    // Length of the seats array, which is also the number of students.
11    const numberOfSeats = seats.length;
12    // Initialize the accumulator for the total moves required.
13    let totalMoves = 0;
14  
15    // Iterate over each seat/student pair to calculate the total moves.
16    for (let index = 0; index < numberOfSeats; index++) {
17        // Increase the total moves by the distance the current student needs to move to reach the current seat.
18        totalMoves += Math.abs(seats[index] - students[index]);
19    }
20  
21    // Return the computed total moves.
22    return totalMoves;
23}
24
Not Sure What to Study? Take the 2-min Quiz:

How does quick sort divide the problem into subproblems?

Time and Space Complexity

The given code sorts two lists, calculates the absolute difference between corresponding elements from each sorted list, and then sums the differences.

Time Complexity:

  1. Sorting both seats and students arrays has a time complexity of O(n log n) where n is the number of elements in each list. Since both lists are sorted independently, the combined time complexity is O(2 * n log n) which simplifies to O(n log n).

  2. The zip() function pairs the elements of both lists, which is O(n) where n is the length of the shorter list. Here we can assume both lists are the same length.

  3. The list comprehension with sum() iterates over the zipped lists to compute the absolute differences and sum them up. This operation is linear with respect to the number of seats/students, so it is O(n).

Thus, the overall time complexity of the provided code is O(n log n) + O(n). Since O(n log n) dominates O(n), the final time complexity is O(n log n).

Space Complexity:

  1. The sorting is done in-place, so it doesn't require additional space proportional to the input size. Thus, the space complexity of the sorting operation is O(1).

  2. The use of zip() and the list comprehension within sum() does not create a new list of size n but instead creates an iterator that generates tuples one by one. Therefore, it only requires constant extra space.

  3. The final expression computes the sum in constant space, adding the absolute difference one pair at a time.

So, the overall space complexity of the provided code is O(1), constant space, since it only uses a fixed amount of additional memory aside from the input lists.

Learn more about how to find time and space complexity quickly using problem constraints.

Fast Track Your Learning with Our Quick Skills Quiz:

Which data structure is used in a depth first search?


Recommended Readings


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫