Searching & SortingProblem 18 of 36
Minimum no. of swaps required to sort the array
Problem Statement
Given an array of n distinct integers, find the minimum number of swaps required to sort the array.
Constraints:
- All elements are distinct
- Only adjacent or non-adjacent swaps are allowed
- Return minimum number of swaps, not the sequence
Example:
- Input:
arr = [4, 3, 2, 1] - Output:
2 - Explanation: Swap 4 and 1, then swap 3 and 2
Example 2:
- Input:
arr = [1, 5, 4, 3, 2] - Output:
2 - Explanation: Swap 5 and 2, then swap 4 and 3
Approach 1: Brute Force (Selection Sort Counting)
Intuition
Use selection sort and count the number of swaps made.
Algorithm
- For each position i from 0 to n-1
- Find the minimum element in the unsorted portion
- If minimum is not at position i, swap and increment count
java
public class Solution {
public int minSwapsSelectionSort(int[] arr) {
int n = arr.length;
int swaps = 0;
for (int i = 0; i < n - 1; i++) {
int minIdx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j;
}
}
if (minIdx != i) {
int temp = arr[i];
arr[i] = arr[minIdx];
arr[minIdx] = temp;
swaps++;
}
}
return swaps;
}
}Note: This doesn't give the minimum number of swaps in all cases!
Complexity Analysis
- Time Complexity: O(n²) - Selection sort
- Space Complexity: O(1) - In-place
Approach 2: Graph Cycles Method (Optimal)
Intuition
Create a graph where each element points to where it should go in the sorted array. Each cycle of length k requires k-1 swaps to fix.
Key Insight
- If an element is at index i but should be at index j (in sorted order), there's an edge i → j
- Elements in a cycle of length k need k-1 swaps to be placed correctly
- Total swaps = Σ(cycle_length - 1) = n - number_of_cycles
Algorithm
- Create pairs of (value, original_index)
- Sort by value to know target positions
- Build a graph: position[i] = where element at index i should go
- Count cycles using DFS/visited array
- Return n - number_of_cycles
java
import java.util.*;
public class Solution {
public int minSwaps(int[] arr) {
int n = arr.length;
// Create pairs of (value, original_index)
int[][] arrPos = new int[n][2];
for (int i = 0; i < n; i++) {
arrPos[i][0] = arr[i];
arrPos[i][1] = i;
}
// Sort by value
Arrays.sort(arrPos, (a, b) -> a[0] - b[0]);
// Track visited elements
boolean[] visited = new boolean[n];
int swaps = 0;
for (int i = 0; i < n; i++) {
// Already visited or in correct position
if (visited[i] || arrPos[i][1] == i) {
continue;
}
// Count cycle length
int cycleLength = 0;
int j = i;
while (!visited[j]) {
visited[j] = true;
j = arrPos[j][1]; // Move to next in cycle
cycleLength++;
}
// k elements in cycle need k-1 swaps
if (cycleLength > 1) {
swaps += (cycleLength - 1);
}
}
return swaps;
}
}Dry Run Example
arr = [4, 3, 2, 1]
sorted positions:
value 1 at index 3 → should be at index 0
value 2 at index 2 → should be at index 1
value 3 at index 1 → should be at index 2
value 4 at index 0 → should be at index 3
arrPos after sorting: [(1, 3), (2, 2), (3, 1), (4, 0)]
Cycle detection:
i=0: arrPos[0].second = 3, follow cycle:
0 → 3 → 0 (back to start)
Cycle: [0, 3], length = 2
i=1: arrPos[1].second = 2, follow cycle:
1 → 2 → 1 (back to start)
Cycle: [1, 2], length = 2
Total swaps = (2-1) + (2-1) = 2
Visual Understanding
Original: [4, 3, 2, 1]
Target: [1, 2, 3, 4]
Cycle 1: 4 → position 0 → should have 1 → at position 3
Index 0 and 3 form a cycle
Cycle 2: 3 → position 1 → should have 2 → at position 2
Index 1 and 2 form a cycle
Each 2-cycle needs 1 swap = 2 swaps total
Complexity Analysis
- Time Complexity: O(n log n) - Sorting dominates
- Space Complexity: O(n) - For arrPos and visited arrays
Alternative: Using HashMap
Using Index Array Directly
Key Takeaways
- Cycle Decomposition: The key insight is that permutation can be decomposed into cycles
- Swaps per Cycle: A cycle of length k needs exactly k-1 swaps
- Formula: Total swaps = n - number_of_cycles
- Graph Representation: Think of array as a graph where i → target_position[i]
- Sorting Required: Need to know target positions, hence O(n log n) is minimum
- Selection Sort: Doesn't give optimal swaps in all cases