Problem Description
There are n couples sitting in 2n seats arranged in a row and want to hold hands.
The people and seats are represented by an integer array row where row[i] is the ID of the person sitting in the ith seat. The couples are numbered in order, the first couple being (0, 1), the second couple being (2, 3), and so on with the last couple being (2n - 2, 2n - 1).
Return the minimum number of swaps so that every couple is sitting side by side. A swap consists of choosing any two people, then they stand up and switch seats.
Example 1:
Input: row = [0,2,1,3] Output: 1 Explanation: We only need to swap the second (row[1]) and third (row[2]) person.
Example 2:
Input: row = [3,2,0,1] Output: 0 Explanation: All couples are already seated side by side.
Constraints:
2n == row.length2 <= n <= 30nis even.0 <= row[i] < 2n- All the elements of
roware unique.
Difficulty: Hard
Tags: greedy, depth-first search, breadth-first search, union find, graph
Rating: 95.28%
Intuition
The key insight is that we can solve this greedily by:
- Processing pairs of adjacent seats from left to right
- For each pair, if they’re not a couple, find the correct partner and swap them
- Keep track of everyone’s position for efficient lookups
This works because each swap we make puts at least one couple together, and we never need to undo a previous swap.
Solution
class Solution:
def minSwapsCouples(self, row: List[int]) -> int:
n = len(row)
swaps = 0
# Dictionary to store each person's current position
pos = {}
for i, person in enumerate(row):
pos[person] = i
# Process each pair of seats
for i in range(0, n, 2):
current = row[i]
# Find who should be their partner
partner = current + 1 if current % 2 == 0 else current - 1
# If wrong person is sitting next to them
if row[i + 1] != partner:
# Find where the partner is sitting
partner_pos = pos[partner]
# Perform the swap
row[i + 1], row[partner_pos] = row[partner_pos], row[i + 1]
# Update positions after swap
pos[row[i + 1]] = i + 1
pos[row[partner_pos]] = partner_pos
swaps += 1
return swaps
Example Walkthrough
Let’s walk through the example row = [0, 2, 1, 3]:
-
Initial state:
[0, 2, 1, 3]- First pair:
[0, 2] - Person 0 should be with Person 1, but they’re with Person 2
- First pair:
-
Find Person 1’s position (index 2)
- Swap Person 2 and Person 1
- After swap:
[0, 1, 2, 3] - Swaps = 1
-
Check second pair:
[2, 3]- Person 2 should be with Person 3
- They’re already together
- No swap needed
Final result: 1 swap
Complexity Analysis
-
Time Complexity: where n is the length of the input array
- We make one pass through the array
- Dictionary lookups are O(1)
- Each position is updated at most once
-
Space Complexity:
- We need a dictionary to store positions of all people
Key Insights
-
The greedy approach works because:
- Each swap directly fixes one couple
- We never need to undo a previous swap
- Local optimal moves lead to the global optimal solution
-
Using a position dictionary makes partner lookups
- Without it, we’d need searches for each swap
-
The solution is optimal because:
- Each misplaced couple requires at least one swap
- Our algorithm performs exactly one swap per misplaced couple