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 N void 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 code int main() { Â Â Â Â int N = 3; Â Â Â Â vector< int > arr = { 1, 5, 4 }; Â Â Â Â minoperation(arr, N); Â Â Â Â return 0; } |
Java
// Java code to implement above approach import 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 approach using 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 N def 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 code if __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!