Given an array of integers, arr[] and an integer k, the task is to find the minimum number of swaps required to group all elements less than or equal to k together in the array so that they form a single contiguous subarray.
In one operation, you may choose any two indices i and j (i < j) and swap the elements at those indices. You may perform this operation any number of times.
Examples:
Input: arr[] = [2, 1, 5, 6, 3], k = 3
Output: 1
Explanation: To bring elements 2, 1, 3 together, swap index 2 with 4 (0-based indexing), i.e. element arr[2] = 5 with arr[4] = 3 such that final array will be arr[] = [2, 1, 3, 6, 5].Input: arr[] = [2, 7, 9, 5, 8, 7, 4], k = 6
Output: 2
Explanation: To bring elements 2, 5, 4 together, swap index 0 with 2 (0-based indexing) and index 4 with 6 (0-based indexing) such that final array will be arr[] = [9, 7, 2, 5, 4, 7, 8].
Table of Content
[Naive Approach] Try Every Window - O(n ^ 2) Time and O(1) Space
The idea is to first count the number of elements less than or equal to k, as they must eventually form a single contiguous subarray. Let this count be 'good'
Then, we examine every possible window of 'good' size and count the number of bad elements (greater than k) inside it.
The window with the fewest bad elements requires the minimum number of swaps, since each bad element must be swapped with a good element outside the window.
- Count the number of elements less than or equal to k and store it in good.
- If good is 0 or equal to the size of the array, return 0.
- Initialize minSwaps to a large value and traverse every possible window of size good.
- Count the number of elements greater than k in the current window.
- Update minSwaps with the minimum of its current value and the count of bad elements in the current window.
- Return minSwaps as the minimum number of swaps required.
#include <bits/stdc++.h>
using namespace std;
int minSwap(vector<int> &arr, int k)
{
int n = arr.size();
// Count the number of elements less than or equal to k
int good = 0;
for (int num : arr)
{
if (num <= k)
good++;
}
// If there are no such elements or all elements are <= k,
// then no swaps are required
if (good == 0 || good == n)
return 0;
int minSwaps = INT_MAX;
// Try every window of size 'good'
for (int start = 0; start <= n - good; start++)
{
// Count the number of elements greater than k
// (bad elements) in the current window
int bad = 0;
for (int i = start; i < start + good; i++)
{
if (arr[i] > k)
bad++;
}
// Update the minimum swaps required
minSwaps = min(minSwaps, bad);
}
return minSwaps;
}
int main()
{
vector<int> arr = {2, 1, 5, 6, 3};
int k = 3;
cout << minSwap(arr, k) << endl;
return 0;
}
import java.util.*;
class GFG {
static int minSwap(int[] arr, int k)
{
int n = arr.length;
// Count the number of elements less than or equal
// to k
int good = 0;
for (int num : arr) {
if (num <= k)
good++;
}
// If there are no such elements or all elements are
// <= k, then no swaps are required
if (good == 0 || good == n)
return 0;
int minSwaps = Integer.MAX_VALUE;
// Try every window of size 'good'
for (int start = 0; start <= n - good; start++) {
// Count the number of elements greater than k
// (bad elements) in the current window
int bad = 0;
for (int i = start; i < start + good; i++) {
if (arr[i] > k)
bad++;
}
// Update the minimum swaps required
minSwaps = Math.min(minSwaps, bad);
}
return minSwaps;
}
public static void main(String[] args)
{
int[] arr = { 2, 1, 5, 6, 3 };
int k = 3;
System.out.println(minSwap(arr, k));
}
}
def minSwap(arr, k):
n = len(arr)
# Count the number of elements less than or equal to k
good = 0
for num in arr:
if num <= k:
good += 1
# If there are no such elements or all elements are <= k,
# then no swaps are required
if good == 0 or good == n:
return 0
minSwaps = float('inf')
# Try every window of size 'good'
for start in range(n - good + 1):
# Count the number of elements greater than k
# (bad elements) in the current window
bad = 0
for i in range(start, start + good):
if arr[i] > k:
bad += 1
# Update the minimum swaps required
minSwaps = min(minSwaps, bad)
return minSwaps
# Driver Code
if __name__ == "__main__":
arr = [2, 1, 5, 6, 3]
k = 3
print(minSwap(arr, k))
using System;
class GFG {
static int minSwap(int[] arr, int k)
{
int n = arr.Length;
// Count the number of elements less than or equal
// to k
int good = 0;
foreach(int num in arr)
{
if (num <= k)
good++;
}
// If there are no such elements or all elements are
// <= k, then no swaps are required
if (good == 0 || good == n)
return 0;
int minSwaps = int.MaxValue;
// Try every window of size 'good'
for (int start = 0; start <= n - good; start++) {
// Count the number of elements greater than k
// (bad elements) in the current window
int bad = 0;
for (int i = start; i < start + good; i++) {
if (arr[i] > k)
bad++;
}
// Update the minimum swaps required
minSwaps = Math.Min(minSwaps, bad);
}
return minSwaps;
}
static void Main()
{
int[] arr = { 2, 1, 5, 6, 3 };
int k = 3;
Console.WriteLine(minSwap(arr, k));
}
}
function minSwap(arr, k)
{
const n = arr.length;
// Count the number of elements less than or equal to k
let good = 0;
for (const num of arr) {
if (num <= k)
good++;
}
// If there are no such elements or all elements are <=
// k, then no swaps are required
if (good === 0 || good === n)
return 0;
let minSwaps = Number.MAX_SAFE_INTEGER;
// Try every window of size 'good'
for (let start = 0; start <= n - good; start++) {
// Count the number of elements greater than k
// (bad elements) in the current window
let bad = 0;
for (let i = start; i < start + good; i++) {
if (arr[i] > k)
bad++;
}
// Update the minimum swaps required
minSwaps = Math.min(minSwaps, bad);
}
return minSwaps;
}
// Driver Code
const arr = [ 2, 1, 5, 6, 3 ];
const k = 3;
console.log(minSwap(arr, k));
Output
1
[Expected Approach] Sliding Window - O(n) Time and O(1) Space
The idea is to first count the number of elements less than or equal to k, as they must eventually form a single contiguous subarray.
We traverse the array again and maintain bad element count while sliding the window one position at a time.
By updating the count based only on the outgoing and incoming elements, each window is processed in constant time.
- Count the number of elements less than or equal to k and store it in good.
- Count the number of elements greater than k in the first window of size good.
- Initialize the answer with the number of bad elements in the first window.
- Slide the window one position at a time across the array.
- Update the bad element count by removing the outgoing element and adding the incoming element.
- Update the answer with the minimum bad element count and return it.
#include <bits/stdc++.h>
using namespace std;
int minSwap(vector<int> &arr, int k)
{
int n = arr.size();
// Count the number of elements less than or equal to k
int good = 0;
for (int num : arr)
{
if (num <= k)
good++;
}
// If there are no such elements or all elements are <= k,
// then no swaps are required
if (good == 0 || good == n)
return 0;
// Count the number of elements greater than k
// (bad elements) in the first window
int bad = 0;
for (int i = 0; i < good; i++)
{
if (arr[i] > k)
bad++;
}
// Initialize the answer with the first window
int minSwaps = bad;
// Slide the window across the array
for (int i = 0, j = good; j < n; i++, j++)
{
// Remove the outgoing element from the window
if (arr[i] > k)
bad--;
// Add the incoming element to the window
if (arr[j] > k)
bad++;
// Update the minimum swaps required
minSwaps = min(minSwaps, bad);
}
return minSwaps;
}
int main()
{
vector<int> arr = {2, 1, 5, 6, 3};
int k = 3;
cout << minSwap(arr, k) << endl;
return 0;
}
import java.util.*;
class GFG {
static int minSwap(int[] arr, int k)
{
int n = arr.length;
// Count the number of elements less than or equal
// to k
int good = 0;
for (int num : arr) {
if (num <= k)
good++;
}
// If there are no such elements or all elements are
// <= k, then no swaps are required
if (good == 0 || good == n)
return 0;
// Count the number of elements greater than k
// (bad elements) in the first window
int bad = 0;
for (int i = 0; i < good; i++) {
if (arr[i] > k)
bad++;
}
// Initialize the answer with the first window
int minSwaps = bad;
// Slide the window across the array
for (int i = 0, j = good; j < n; i++, j++) {
// Remove the outgoing element from the window
if (arr[i] > k)
bad--;
// Add the incoming element to the window
if (arr[j] > k)
bad++;
// Update the minimum swaps required
minSwaps = Math.min(minSwaps, bad);
}
return minSwaps;
}
public static void main(String[] args)
{
int[] arr = { 2, 1, 5, 6, 3 };
int k = 3;
System.out.println(minSwap(arr, k));
}
}
def minSwap(arr, k):
n = len(arr)
# Count the number of elements less than or equal to k
good = 0
for num in arr:
if num <= k:
good += 1
# If there are no such elements or all elements are <= k,
# then no swaps are required
if good == 0 or good == n:
return 0
# Count the number of elements greater than k
# (bad elements) in the first window
bad = 0
for i in range(good):
if arr[i] > k:
bad += 1
# Initialize the answer with the first window
minSwaps = bad
# Slide the window across the array
i, j = 0, good
while j < n:
# Remove the outgoing element from the window
if arr[i] > k:
bad -= 1
# Add the incoming element to the window
if arr[j] > k:
bad += 1
# Update the minimum swaps required
minSwaps = min(minSwaps, bad)
i += 1
j += 1
return minSwaps
# Driver Code
if __name__ == "__main__":
arr = [2, 1, 5, 6, 3]
k = 3
print(minSwap(arr, k))
using System;
class GFG {
static int minSwap(int[] arr, int k)
{
int n = arr.Length;
// Count the number of elements less than or equal
// to k
int good = 0;
foreach(int num in arr)
{
if (num <= k)
good++;
}
// If there are no such elements or all elements are
// <= k, then no swaps are required
if (good == 0 || good == n)
return 0;
// Count the number of elements greater than k
// (bad elements) in the first window
int bad = 0;
for (int i = 0; i < good; i++) {
if (arr[i] > k)
bad++;
}
// Initialize the answer with the first window
int minSwaps = bad;
// Slide the window across the array
for (int i = 0, j = good; j < n; i++, j++) {
// Remove the outgoing element from the window
if (arr[i] > k)
bad--;
// Add the incoming element to the window
if (arr[j] > k)
bad++;
// Update the minimum swaps required
minSwaps = Math.Min(minSwaps, bad);
}
return minSwaps;
}
static void Main()
{
int[] arr = { 2, 1, 5, 6, 3 };
int k = 3;
Console.WriteLine(minSwap(arr, k));
}
}
function minSwap(arr, k)
{
const n = arr.length;
// Count the number of elements less than or equal to k
let good = 0;
for (const num of arr) {
if (num <= k)
good++;
}
// If there are no such elements or all elements are <=
// k, then no swaps are required
if (good === 0 || good === n)
return 0;
// Count the number of elements greater than k
// (bad elements) in the first window
let bad = 0;
for (let i = 0; i < good; i++) {
if (arr[i] > k)
bad++;
}
// Initialize the answer with the first window
let minSwaps = bad;
// Slide the window across the array
for (let i = 0, j = good; j < n; i++, j++) {
// Remove the outgoing element from the window
if (arr[i] > k)
bad--;
// Add the incoming element to the window
if (arr[j] > k)
bad++;
// Update the minimum swaps required
minSwaps = Math.min(minSwaps, bad);
}
return minSwaps;
}
// Driver Code
const arr = [ 2, 1, 5, 6, 3 ];
const k = 3;
console.log(minSwap(arr, k));
Output
1