Minimize operations to make Array a permutation
Last Updated :
01 Aug, 2023
Given an array arr of n integers. You want to make this array a permutation of integers 1 to n. In one operation you can choose two integers i (0 ≤ i < n) and x (x > 0), then replace arr[i] with arr[i] mod x, the task is to determine the minimum number of operations to achieve this goal otherwise return -1.
Note: A permutation is an array consisting of n distinct integers from 1 to n in arbitrary order.
Examples:
Input: n = 2, arr = {1, 7}
Output:1
Explanation: In the first operation, you will choose i = 1, and x = 5, so the arr[1] will be (7%5) = 2, now the array {1, 2} is a permutation.
Input: n = 3, arr = {1, 5, 4}
Output: -1
Explanation: It’s not possible to make the 3rd element 2, or 3, so the answer will be -1.
Approach: This problem can be solved using Greedy Algorithm and Modulo Arithmetic.
The idea is to use the concept that any number x can be converted to y if y=x%m then y lies between 0 and ceil(x/2)-1. Thus, in the array, we just need to convert those numbers that are greater than n and those numbers that are less than or equal to n but are duplicates. Now just greedily pick a smaller number for conversion to a smaller element.
Steps that were to follow the above approach:
- Create a vis array to mark those permutations which have been found in the array or have been made by using the given operation.
- Sort the array to greedily pick smaller elements for conversion to smaller elements.
- Create an array v to store the maximum possible number that can be made from numbers > n and duplicates of numbers ≤ n
- Make a variable j to iterate from 1 to n and check if we have made this permutation.
- Iterate through vector v and initially iterate j to the permutation not found so far:
- If (v[i] ≥ permutation not found) then this permutation can be made and keep iterating forward.
- Otherwise making the permutation is not possible.
Below is the code to implement the above steps:
C++
#include <bits/stdc++.h>
using namespace std;
int makePermutation( int n, vector< int >& arr)
{
vector< int > vis(n + 1);
sort(arr.begin(), arr.end());
vector< int > v;
for ( int i = 1; i <= n; i++) {
if (arr[i - 1] <= n) {
if (vis[arr[i - 1]])
v.push_back(arr[i - 1] & 1
? arr[i - 1] / 2
: arr[i - 1] / 2 - 1);
vis[arr[i - 1]] = 1;
}
else
v.push_back(arr[i - 1] & 1
? arr[i - 1] / 2
: arr[i - 1] / 2 - 1);
}
int j = 1;
int ans = 0;
for ( int i = 0; i < v.size(); i++) {
while (vis[j])
j++;
if (v[i] >= j)
j++;
else
return -1;
ans++;
}
return ans;
}
int main()
{
vector< int > arr = { 1, 7 };
cout << makePermutation(2, arr) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int makePermutation( int n,
List<Integer> arr)
{
List<Integer> vis = new ArrayList<>(
Collections.nCopies(n + 1 , 0 ));
Collections.sort(arr);
List<Integer> v = new ArrayList<>();
for ( int i = 1 ; i <= n; i++) {
if (arr.get(i - 1 ) <= n) {
if (vis.get(arr.get(i - 1 )) != 0 )
v.add((arr.get(i - 1 ) & 1 ) == 1
? arr.get(i - 1 ) / 2
: arr.get(i - 1 ) / 2 - 1 );
vis.set(arr.get(i - 1 ), 1 );
}
else
v.add((arr.get(i - 1 ) & 1 ) == 1
? arr.get(i - 1 ) / 2
: arr.get(i - 1 ) / 2 - 1 );
}
int j = 1 ;
int ans = 0 ;
for ( int i = 0 ; i < v.size(); i++) {
while (vis.get(j) != 0 )
j++;
if (v.get(i) >= j)
j++;
else
return - 1 ;
ans++;
}
return ans;
}
public static void main(String[] args)
{
List<Integer> arr
= new ArrayList<>(Arrays.asList( 1 , 7 ));
System.out.println(makePermutation( 2 , arr));
}
}
|
Python3
def makePermutation(n, arr):
vis = [ 0 ] * (n + 1 )
arr.sort()
v = []
for i in range ( 1 , n + 1 ):
if arr[i - 1 ] < = n:
if vis[arr[i - 1 ]]:
v.append(arr[i - 1 ] / / 2 if arr[i - 1 ] & 1 else arr[i - 1 ] / / 2 - 1 )
vis[arr[i - 1 ]] = 1
else :
v.append(arr[i - 1 ] / / 2 if arr[i - 1 ] & 1 else arr[i - 1 ] / / 2 - 1 )
j = 1
ans = 0
for i in range ( len (v)):
while vis[j]:
j + = 1
if v[i] > = j:
j + = 1
else :
return - 1
ans + = 1
return ans
if __name__ = = '__main__' :
arr = [ 1 , 7 ]
print (makePermutation( 2 , arr))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
static int MakePermutation( int n, List< int > arr)
{
List< int > vis = new List< int >( new int [n + 1]);
arr.Sort();
List< int > v = new List< int >();
for ( int i = 1; i <= n; i++)
{
if (arr[i - 1] <= n)
{
if (vis[arr[i - 1]] != 0)
v.Add((arr[i - 1] & 1) != 0 ? arr[i - 1] / 2 :
arr[i - 1] / 2 - 1);
vis[arr[i - 1]] = 1;
}
else
{
v.Add((arr[i - 1] & 1) != 0 ? arr[i - 1] / 2 : arr[i - 1] / 2 - 1);
}
}
int j = 1;
int ans = 0;
for ( int i = 0; i < v.Count; i++)
{
while (vis[j] != 0)
j++;
if (v[i] >= j)
j++;
else
return -1;
ans++;
}
return ans;
}
static void Main( string [] args)
{
List< int > arr = new List< int > { 1, 7 };
Console.WriteLine(MakePermutation(2, arr));
}
}
|
Javascript
function makePermutation(n, arr) {
const vis = new Array(n + 1).fill(0);
arr.sort((a, b) => a - b);
const v = [];
for (let i = 1; i <= n; i++) {
if (arr[i - 1] <= n) {
if (vis[arr[i - 1]]) {
v.push(arr[i - 1] & 1 ? arr[i - 1] / 2 : arr[i - 1] / 2 - 1);
}
vis[arr[i - 1]] = 1;
} else {
v.push(arr[i - 1] & 1 ? arr[i - 1] / 2 : arr[i - 1] / 2 - 1);
}
}
let j = 1;
let ans = 0;
for (let i = 0; i < v.length; i++) {
while (vis[j]) {
j++;
}
if (v[i] >= j) {
j++;
} else {
return -1;
}
ans++;
}
return ans;
}
const arr = [1, 7];
console.log(makePermutation(2, arr));
|
Time Complexity: O(N*log(N))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...