Find the minimum swaps to group K elements.
Last Updated :
30 Nov, 2023
Given an integer array arr[] of length n and an integer K, the task is to determine the minimum number of swaps required to group at least K occurrences of the same element consecutively in the array. If it is not possible to group the same number K times consecutive then print -1.
Examples:
Input: n = 8, arr[] = { 1, 2, 2, 3, 4, 5, 2, 6}, K = 3
Output: 3
Explanation: As 2 is the number that has a frequency equal to K the 2 at index 6 swaps 3, 4, 5 right to make the same number K times consecutive.
Input: n = 10, arr[] = { 1, 2, 5, 1, 4, 6, 5, 7, 1, 5}, K = 3
Output: 5
Explanation: 1 and 5 have at least K frequency but number 5 required only 5 swaps to make the same number K times consecutive, whereas 1 required 6 swaps.
Approach: To solve the problem Using Hash Map follow the below steps:
- Use of a map to store the indices of occurrences for each element in the array.
- Iterate through the map and calculate swaps needed to group 'K' occurrences of an element.
- Create a window of size K and calculate initial K swaps by calculating the difference in the index of two consecutive elements.
- Slide the window of 'K' occurrences through the remaining occurrences and calculate swaps by removing from the starting and
adding differences in the index at the end of the sliding window one by one.
[swap = swap - (it.second[i+1]-it.second[i]-1)+(it.second[i+K]-it.second[i+K - 1] - 1); ] - Keep track of the minimum swaps needed across all elements by storing the minimum swap in ans variable.
- Return the minimum swaps obtained or -1 if grouping 'K' occurrences isn't possible.
Below is the implementation of the above approach:
C++
// C++ code to implement above code
#include <bits/stdc++.h>
using namespace std;
// Function to find minimum swaps
int MinSwap(vector<int>& v, int n, int k)
{
// map to store the indices of occurrence
// of each elements
unordered_map<int, vector<int> > m;
// To store the minimum answer
int ans = INT_MAX;
// Pushing indixes of each element
for (int i = 0; i < n; i++) {
m[v[i]].push_back(i);
}
// Traversing the map
for (auto& it : m) {
// Swap window
if (it.second.size() >= k) {
int swap = 0;
for (int i = 0; i < k - 1; i++) {
int a = it.second[i + 1];
int b = it.second[i];
// Adding the diff betweem the
// adjacent index
swap += a - b - 1;
}
// Storing minimum of swap window
ans = min(ans, swap);
// Traverse the indices of occurrence
// of each element and slide
// the window to find min swap
for (int i = 0; i + k < it.second.size(); i++) {
swap = swap
- (it.second[i + 1] - it.second[i]
- 1)
+ (it.second[i + k]
- it.second[i + k - 1] - 1);
ans = min(ans, swap);
}
}
}
// Return ans
if (ans == INT_MAX)
return -1;
else
return ans;
}
// Driver code
int main()
{
// Input 1
int n = 10;
vector<int> v = { 1, 2, 5, 1, 4, 6, 5, 7, 1, 5 };
// Target
int K = 3;
// Function call
int ans = MinSwap(v, n, K);
cout << ans << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
// Function to find minimum swaps
static int MinSwap(List<Integer> v, int n, int k) {
// Map to store the indices of occurrence of each element
Map<Integer, List<Integer>> m = new HashMap<>();
// To store the minimum answer
int ans = Integer.MAX_VALUE;
// Pushing indices of each element
for (int i = 0; i < n; i++) {
int value = v.get(i);
if (!m.containsKey(value)) {
m.put(value, new ArrayList<>());
}
m.get(value).add(i);
}
// Traversing the map
for (Map.Entry<Integer, List<Integer>> entry : m.entrySet()) {
List<Integer> indices = entry.getValue();
// Swap window
if (indices.size() >= k) {
int swap = 0;
for (int i = 0; i < k - 1; i++) {
int a = indices.get(i + 1);
int b = indices.get(i);
// Adding the difference between the adjacent index
swap += a - b - 1;
}
// Storing the minimum of the swap window
ans = Math.min(ans, swap);
// Traverse the indices of occurrence of each element and slide the window to find min swap
for (int i = 0; i + k < indices.size(); i++) {
swap = swap - (indices.get(i + 1) - indices.get(i) - 1) + (indices.get(i + k) - indices.get(i + k - 1) - 1);
ans = Math.min(ans, swap);
}
}
}
// Return ans
if (ans == Integer.MAX_VALUE)
return -1;
else
return ans;
}
public static void main(String[] args) {
// Input
int n = 10;
List<Integer> v = new ArrayList<>();
v.add(1);
v.add(2);
v.add(5);
v.add(1);
v.add(4);
v.add(6);
v.add(5);
v.add(7);
v.add(1);
v.add(5);
// Target
int k = 3;
// Function call
int ans = MinSwap(v, n, k);
System.out.println(ans);
}
}
Python3
# Python code to implement above code
# Function to find minimum swaps
def min_swap(arr, n, k):
# Dictionary to store the indices of occurrence of each element
m = {}
# To store the minimum answer
ans = float('inf')
# Pushing indices of each element into the dictionary
for i in range(n):
if arr[i] not in m:
m[arr[i]] = []
m[arr[i]].append(i)
# Traversing the dictionary
for key, value in m.items():
# Swap window
if len(value) >= k:
swap = 0
for i in range(k - 1):
a = value[i + 1]
b = value[i]
# Adding the difference between the adjacent index
swap += a - b - 1
# Storing the minimum of the swap window
ans = min(ans, swap)
# Traverse the indices of occurrence of each element and slide
# the window to find min swap
for i in range(len(value) - k):
swap = swap - (value[i + 1] - value[i] - 1) + \
(value[i + k] - value[i + k - 1] - 1)
ans = min(ans, swap)
# Return ans
if ans == float('inf'):
return -1
else:
return ans
# Driver code
# Input
n = 10
arr = [1, 2, 5, 1, 4, 6, 5, 7, 1, 5]
# Target
k = 3
# Function call
result = min_swap(arr, n, k)
print(result)
C#
// C# code to implement above code
using System;
using System.Collections.Generic;
class GFG
{
// Function to find minimum swaps
static int MinSwap(List<int> v, int n, int k)
{
// Dictionary to store the indices of occurrence
// of each elements
Dictionary<int, List<int>> m = new Dictionary<int, List<int>>();
// To store the minimum answer
int ans = int.MaxValue;
// Pushing indixes of each element
for (int i = 0; i < n; i++)
{
if (!m.ContainsKey(v[i]))
{
m[v[i]] = new List<int>();
}
m[v[i]].Add(i);
}
// Traversing the map
foreach (var it in m)
{
// Swap window
if (it.Value.Count >= k)
{
int swap = 0;
for (int i = 0; i < k - 1; i++)
{
int a = it.Value[i + 1];
int b = it.Value[i];
// Adding the diff betweem the
// adjacent index
swap += a - b - 1;
}
// Storing minimum of swap window
ans = Math.Min(ans, swap);
// Traverse the indices of occurrence
// of each element and slide
// the window to find min swap
for (int i = 0; i + k < it.Value.Count; i++)
{
swap = swap - (it.Value[i + 1] - it.Value[i] - 1) + (it.Value[i + k] - it.Value[i + k - 1] - 1);
ans = Math.Min(ans, swap);
}
}
}
// Return ans
if (ans == int.MaxValue)
return -1;
else
return ans;
}
// Driver code
static void Main(string[] args)
{
// Input 1
int n = 10;
List<int> v = new List<int> { 1, 2, 5, 1, 4, 6, 5, 7, 1, 5 };
// Target
int K = 3;
// Function call
int ans = MinSwap(v, n, K);
Console.WriteLine(ans);
}
}
JavaScript
function MinSwap(arr, k) {
// Map to store the indices of occurrence of each element
let map = new Map();
// To store the minimum answer
let ans = Infinity;
// Pushing indices of each element
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
map.set(arr[i], []);
}
map.get(arr[i]).push(i);
}
// Traversing the map
map.forEach((indices) => {
// Swap window
if (indices.length >= k) {
let swap = 0;
for (let i = 0; i < k - 1; i++) {
let a = indices[i + 1];
let b = indices[i];
// Adding the difference between the adjacent index
swap += a - b - 1;
}
// Storing the minimum of the swap window
ans = Math.min(ans, swap);
// Traverse the indices of occurrence of each element and slide the window to find the minimum swap
for (let i = 0; i + k < indices.length; i++) {
swap = swap - (indices[i + 1] - indices[i] - 1) + (indices[i + k] - indices[i + k - 1] - 1);
ans = Math.min(ans, swap);
}
}
});
// Return ans
if (ans === Infinity) {
return -1;
} else {
return ans;
}
}
// Driver code
const arr = [1, 2, 5, 1, 4, 6, 5, 7, 1, 5];
const k = 3;
// Function call
const ans = MinSwap(arr, k);
console.log(ans);
Time Complexity: O(n)
Auxillary Space: O(n), as maximum elements in a map can be up to N.
Similar Reads
Minimum swaps to minimize the sum of first K elements of the Permutation Given a permutation A[] of first N integers (i.e. array contains integers from 1 to N exactly once) and an integer K, the task is to find the minimum number of swaps needed to minimize the sum of the first K elements of the array. Examples: Input: N = 4, K = 2, A[] = {3, 4, 1, 2}Output: 2Explanation
6 min read
Minimum increment operations to make K elements equal Given an array arr[] of N elements and an integer K, the task is to make any K elements of the array equal by performing only increment operations i.e. in one operation, any element can be incremented by 1. Find the minimum number of operations required to make any K elements equal.Examples: Input:
11 min read
Minimum increment operations to make K elements equal Given an array arr[] of N elements and an integer K, the task is to make any K elements of the array equal by performing only increment operations i.e. in one operation, any element can be incremented by 1. Find the minimum number of operations required to make any K elements equal.Examples: Input:
11 min read
Minimum increment operations to make K elements equal Given an array arr[] of N elements and an integer K, the task is to make any K elements of the array equal by performing only increment operations i.e. in one operation, any element can be incremented by 1. Find the minimum number of operations required to make any K elements equal.Examples: Input:
11 min read
Minimum Swaps required to group all 1's together Given an array of 0's and 1's, we need to write a program to find the minimum number of swaps required to group all 1's present in the array together.Examples: Input: arr[] = [1, 0, 1, 0, 1]Output: 1Explanation: Only 1 swap is required to group all 1's together. Swapping index 1 with 4 will give arr
9 min read
Minimum swaps so that binary search can be applied Given an unsorted array of length n and an integer k, find the minimum swaps to get the position of k before using the binary search. Here we can swap any two numbers as many times as we want. If we cannot get the position by swapping elements, print "-1".Examples: Input : arr = {3, 10, 6, 7, 2, 5,
14 min read