Given an array arr[] of size N, the task is to find the minimum number of operations required to make the array a permutation of numbers in range [1, N] where, in each operation, an element at any index i can be replaced by arr[i]%k (k = any value greater than 0). Return -1 if the array cannot be made a permutation of numbers in range [1, N].
Examples:
Input: arr [] = {1, 7}, N = 2
Output: 1
Explanation: The only possible sequence of operations which minimizes the no of operations is
Choose i = 1, k = 5. Perform arr[1] = arr[1] % 5 = 2.ÂInput: arr [] = {1,5,4}, N = 3
Output: -1
Explanation: It is impossible to obtain a permutation of integers from 1 to N.
Approach: The problem can be solved on the basis of the following observation.
x % y < (x/2) if x ≥ y, and
x % y = x if x < y.As bigger is x, the longer the range of values that can be obtained after one mod operation.Â
So try to, assign smaller arr[i] to smaller numbers in the resulting permutation.Although, if arr[i] satisfies 1 ≤ arr[i] ≤ N, just leave it there and use it in the resulting permutation.
if multiple arr[i] satisfy the same condition and have the same value, just choose one.Â
Let’s suppose in the optimal solution, l is changed to m and n to l for some n > l > m (l, m, n are values, not indices).Â
Then keeping l intact and changing n to m uses 1 less operation.Â
And, if it is possible to change n to l, then it must be possible to change n to m.
Follow the steps mentioned below to implement the approach:
- Sort the array.
- If 1 ≤ arr[i] ≤ N and it is the first occurrence of the element with value arr[i], leave it there.
- Else, let the current least unassigned value in the resulting permutation be x:
- If x < arr[i]/2, assign the current element to value x and add the number of operations by 1.
- Else, output −1 directly.
Below is the implementation of the above approach.
C++
// C++ code to implement above approach#include <bits/stdc++.h>using namespace std;Â
// Function to find minimum operations// used to make permutation of 1 to Nvoid minoperation(vector<int> arr, int N){    set<int> st;    vector<int> rem;         // Storing one instance of every element     // from 1 to N    for (int i = 1; i <= N; i++) {        st.insert(i);    }Â
    for (int i = 0; i < N; i++) {        if (st.find(arr[i]) != st.end())            st.erase(arr[i]);        else            rem.push_back(arr[i]);    }         // Sorting in descending order    sort(rem.begin(), rem.end());    reverse(rem.begin(), rem.end());Â
    int pt = 0;    bool flag = false;Â
    for (auto& x : rem) {        auto it = st.end();        it--;        int p = (*it);        if (p > (x - 1) / 2) {            flag = true;            break;        }        st.erase(it);    }Â
    if (flag) {        // Not possible to make permutation.        cout << "-1";    }    else {        // Minimum number of operation required.        cout << rem.size();    }}Â
// Driver codeint main(){Â Â Â Â int N = 3;Â Â Â Â vector<int> arr = { 1, 5, 4 };Â Â Â Â minoperation(arr, N);Â Â Â Â return 0;} |
Java
// Java code to implement above approachimport java.util.*;class GFG{Â
  // Function to find minimum operations  // used to make permutation of 1 to N  static void minoperation(int[] arr, int N)  {    HashSet<Integer> st = new HashSet<Integer>();    Vector<Integer> rem = new Vector<Integer>();Â
    // Storing one instance of every element     // from 1 to N    for (int i = 1; i <= N; i++) {      st.add(i);    }Â
    for (int i = 0; i < N; i++) {      if (st.contains(arr[i]))        st.remove(arr[i]);      else        rem.add(arr[i]);    }Â
    // Sorting in descending order    Collections.sort(rem,Collections.reverseOrder());Â
    boolean flag = false;Â
    for (int x : rem) {      int it = st.size();      it--;      int p = new ArrayList<>(st).get(it);      if (p > (x - 1) / 2) {        flag = true;        break;      }      st.remove(it);    }Â
    if (flag) {      // Not possible to make permutation.      System.out.print("-1");    }    else {      // Minimum number of operation required.      System.out.print(rem.size());    }  }Â
  // Driver code  public static void main(String[] args)  {    int N = 3;    int[] arr = { 1, 5, 4 };    minoperation(arr, N);  }}Â
// This code is contributed by 29AjayKumar |
C#
// C# code to implement above approachusing System;using System.Collections.Generic;class GFG{Â
  // Function to find minimum operations  // used to make permutation of 1 to N  static void minoperation(int[] arr, int N)  {    HashSet<int> st = new HashSet<int>();    List<int> rem = new List<int>();Â
    // Storing one instance of every element     // from 1 to N    for (int i = 1; i <= N; i++)    {      st.Add(i);    }Â
    for (int i = 0; i < N; i++)    {      if (st.Contains(arr[i]))        st.Remove(arr[i]);      else        rem.Add(arr[i]);    }Â
    // Sorting in descending order    rem.Sort();    rem.Reverse();Â
    bool flag = false;Â
    foreach (int x in rem)    {      int it = st.Count;      it--;      int p = new List<int>(st)[it];      if (p > (x - 1) / 2)      {        flag = true;        break;      }      st.Remove(it);    }Â
    if (flag)    {             // Not possible to make permutation.      Console.Write("-1");    }    else    {             // Minimum number of operation required.      Console.Write(rem.Count);    }  }Â
  // Driver code  public static void Main()  {    int N = 3;    int[] arr = { 1, 5, 4 };    minoperation(arr, N);  }}Â
// This code is contributed by Saurabh jaiswal |
Python3
# Python 3 code to implement above approachÂ
# Function to find minimum operations# used to make permutation of 1 to Ndef minoperation(arr, N):Â Â Â Â st = set([])Â Â Â Â rem = []Â
    # Storing one instance of every element    # from 1 to N    for i in range(1, N + 1):        st.add(i)Â
    for i in range(N):        if (arr[i] in st):            st.remove(arr[i])Â
        else:            rem.append(arr[i])Â
    # Sorting in descending order    rem.sort()    rem.reverse()Â
    pt = 0    flag = FalseÂ
    for x in rem:        it = len(st)        it -= 1        p = list(st)[it]        if (p > (x - 1) / 2):            flag = True            breakÂ
        st.remove(it)Â
    if (flag):        # Not possible to make permutation.        print("-1")Â
    else:        # Minimum number of operation required.        print(len(rem))Â
# Driver codeif __name__ == "__main__":Â
    N = 3    arr = [1, 5, 4]    minoperation(arr, N)Â
    # This code is contributed by ukasp. |
Javascript
<script>Â Â Â Â Â Â Â Â // JavaScript code for the above approach Â
        // Function to find minimum operations        // used to make permutation of 1 to N        function minoperation(arr, N)        {            let st = new Set();            let rem = [];Â
            // Storing one instance of every element             // from 1 to N            for (let i = 1; i <= N; i++) {                st.add(i);            }Â
            for (let i = 0; i < N; i++) {                if (st.has(arr[i]))                    st.delete(arr[i]);                else                    rem.push(arr[i]);            }Â
            // Sorting in descending order            rem.sort(function (a, b) { return b - a })            rem.reverse();Â
            let pt = 0;            let flag = false;Â
            for (let x of rem) {                let it = [...st].pop();Â
                let p = (it);                if (p > Math.floor((x - 1) / 2)) {                    flag = true;                    break;                }                st.delete(it);            }Â
            if (flag)            {                             // Not possible to make permutation.                document.write(-1)            }            else {                // Minimum number of operation required.                document.write(rem.size)            }        }Â
        // Driver code        let N = 3;        let arr = [1, 5, 4];        minoperation(arr, N);Â
  // This code is contributed by Potta Lokesh    </script> |
Â
Â
-1
Â
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

… [Trackback]
[…] Info to that Topic: geeksforgeeks.org/minimize-modulo-operations-to-make-given-array-a-permutation-of-1-n/ […]
… [Trackback]
[…] Information to that Topic: geeksforgeeks.org/minimize-modulo-operations-to-make-given-array-a-permutation-of-1-n/ […]