Array · 30 of 36
Minimum swaps required bring elements less equal K together
Get all the small kids to sit next to each other on one bench by swapping seats as few times as possible.
- Simple way
- time O(n^2)
room O(1) - Clever way
- time O(n)
room O(1)
The problem, simply
You get an array of positive numbers and a number k. Call a number small if it is at most k, and big otherwise. A swap exchanges any two numbers, near or far.
Find the fewest swaps that put all the small numbers next to each other, in one unbroken stretch. The order inside the stretch does not matter.
A story to remember it
Picture it
k = 4. Green numbers are small (at most 4), red numbers are big. There are 4 small numbers, so they will fill some 4 seats in a row. The stretch 1, 9, 2, 3 holds only one big number: one swap fixes it.
- done
- rejected
Examples
A small case
- In
arr = [2, 1, 5, 6, 3], k = 3- Out
1
Small numbers: 2, 1, 3. Swap 5 and 3 to get [2, 1, 3, 6, 5].
A normal case
- In
arr = [6, 1, 9, 2, 3, 8, 4, 7], k = 4- Out
1
The window 1, 9, 2, 3 has one big number. Swap 9 with 4 to get [6, 1, 4, 2, 3, 8, 9, 7].
Every window costs the same
- In
arr = [2, 7, 9, 5, 8, 7, 4], k = 5- Out
2
Three small numbers, so the window is 3 wide. Every window of 3 holds exactly 2 big numbers.
All small
- In
arr = [1, 2, 3], k = 5- Out
0
They are already together.
None small
- In
arr = [7, 8, 9], k = 2- Out
0
There is nothing to gather.
Way 1: the simple way
Count the small numbers, w. Try every window of w seats, and count its big numbers from scratch. The smallest count is the answer.
w= how many numbers are at mostk.- For each start
ifrom 0 ton - w, count the big numbers inarr[i..i+w-1]. - Keep the smallest count.
class Solution {
public int minSwap(int[] arr, int k) {
int n = arr.length, w = 0;
for (int x : arr) if (x <= k) w++; // how wide the window must be
int best = w; // a window can never need more than w swaps
for (int i = 0; i + w <= n; i++) {
int big = 0;
for (int j = i; j < i + w; j++) if (arr[j] > k) big++;
best = Math.min(best, big);
}
return best;
}
}How long it takes: up to n windows, each counted in up to n steps, O(n^2). Extra room: a few counters, O(1).
Way 2: the clever way
Do not recount each window. When the window slides one seat right, one number leaves on the left and one joins on the right. Fix the count with those two.
- Count
w, the number of small numbers. - Count the big numbers in the first window,
arr[0..w-1]. - Slide: for
ifromwton - 1, ifarr[i]is big add 1, and ifarr[i - w](the one leaving) is big subtract 1. - The smallest count seen is the answer.
Why is the cost of a window its number of big numbers? Each big number inside must leave, and each swap can bring in exactly one small number from outside. There are exactly enough small numbers outside, because the window is as wide as the count of small numbers.
Slide a window as wide as the small numbers
01 / 07
Count the small numbers, at most 4: there are 4. So the window is 4 seats wide. Green is small, red is big.
- k
- 4
- width
- 4
- done
- answer
- rejected
- just added
class Solution {
public int minSwap(int[] arr, int k) {
int n = arr.length, w = 0;
for (int x : arr) if (x <= k) w++; // window width
if (w == 0) return 0;
int big = 0;
for (int i = 0; i < w; i++) if (arr[i] > k) big++; // the first window
int best = big;
for (int i = w; i < n; i++) {
if (arr[i] > k) big++; // a big number joins on the right
if (arr[i - w] > k) big--; // a big number leaves on the left
best = Math.min(best, big);
}
return best;
}
}How long it takes: one count and one slide, O(n). Extra room: a few counters, O(1).
Watch out for
- If no number is small, the window is 0 wide. Return 0 before building it.
- "Small" means at most
k, so use<=. A number equal tokmust be gathered too. - Return the fewest big numbers in a window, not the most small numbers. They point to the same window but are different numbers.
What interviewers ask next
- Return which swaps to make. Remember the start of the best window, then pair each big number inside with a small number outside.
- Group all the 1s in a binary array with fewest swaps. Same thing: the window is as wide as the count of 1s.
- The array is a circle (LeetCode 2134). Slide the window over the array twice in a row, using
i % n. - Fewest adjacent swaps instead of any swaps. Then distance matters: gather the items toward their median position, using prefix sums.
Remember this
Grown-up words: the frame is a fixed-size sliding window, the bench is the array, and adding the one that joins and removing the one that leaves is an incremental update.