Open In App

Find the minimum swaps to group K elements.

Last Updated : 30 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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);


Output

5











Time Complexity: O(n)
Auxillary Space: O(n), as maximum elements in a map can be up to N.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads