Given an array arr[] of N integers. the task is to find the minimum number of operations required to make all the elements of the array distinct using the following operations.
- Remove one element from the starting of the array arr[] and append any integer to the end.
- Remove one element from the end of the array arr[] and prepend any integer to the beginning.
Examples:
Input: arr[] = {1, 3, 3, 5, 1, 9, 4, 1} Output: 4 Explanation: Remove 1 from end and add 5 at starting [5, 1, 3, 3, 5, 1, 9, 4] Remove 5 from start and add 7 at end [1, 3, 3, 5, 1, 9, 4, 7] Remove 1 from start and add 8 at end [3, 3, 5, 1, 9, 4, 7, 8] Remove 3 from start and add 2 at end [3, 5, 1, 9, 4, 7, 8, 2]
Input: arr[] = {1, 2, 3, 5, 4} Output: 0
Approach: To solve the problem follow the below idea and steps:
- At first, find the subarray containing all unique character and store its starting index at i and ending index at j,
- Now, apply the formula 2*min(i, N – j – 1) + max(i, N – j – 1) and return the answer,
- Why the formula works?
- As, we have to remove the elements from start to i and from j to end, so choose which is minimum, then add twice of that with the maximum.
- There is an edge case, where the multiple max size subarray come then give the preference to that subarray whose starting index is 0 or ending index is
N-1.
Follow the steps mentioned below to solve the problem:
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
pair< int , int > findMax( int a[], int n)
{
unordered_map< int , int > index;
int ans = 0, x = -1, y = -1;
for ( int i = 0, j = 0; i < n; i++) {
j = max(index[a[i]], j);
if ((i - j + 1) >= ans) {
if ((i - j + 1) == ans) {
if (i == (n - 1) || j == 0) {
ans = i - j + 1;
x = i;
y = j;
}
}
else {
ans = i - j + 1;
x = i;
y = j;
}
}
index[a[i]] = i + 1;
}
return { x, y };
}
int findMinOperations( int * arr, int n)
{
pair< int , int > p = findMax(arr, n);
int i = p.second;
int j = p.first;
return 2 * min(i, n - j - 1)
+ max(i, n - j - 1);
}
int main()
{
int arr[] = { 1, 3, 3, 5, 1, 9, 4, 1 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << findMinOperations(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class pair {
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
class GFG {
public static pair findMax( int [] a, int n)
{
HashMap<Integer, Integer> index
= new HashMap<Integer, Integer>();
int ans = 0 , x = - 1 , y = - 1 ;
for ( int i = 0 , j = 0 ; i < n; i++) {
if (index.get(a[i]) != null ) {
j = Math.max(index.get(a[i]), j);
}
if ((i - j + 1 ) >= ans) {
if ((i - j + 1 ) == ans) {
if (i == (n - 1 ) || j == 0 ) {
ans = i - j + 1 ;
x = i;
y = j;
}
}
else {
ans = i - j + 1 ;
x = i;
y = j;
}
}
index.put(a[i], i + 1 );
}
return new pair(x, y);
}
public static int findMinOperations( int [] arr, int n)
{
pair p = findMax(arr, n);
int i = p.second;
int j = p.first;
return 2 * Math.min(i, n - j - 1 )
+ Math.max(i, n - j - 1 );
}
public static void main(String[] args)
{
int [] arr = { 1 , 3 , 3 , 5 , 1 , 9 , 4 , 1 };
int N = arr.length;
System.out.print(findMinOperations(arr, N));
}
}
|
Python3
def findMax(a, n):
index = {}
ans = 0
x = - 1
y = - 1
j = 0
for i in range (n):
if a[i] in index:
j = max (index[a[i]], j)
if ((i - j + 1 ) > = ans):
if ((i - j + 1 ) = = ans):
if (i = = (n - 1 ) or j = = 0 ):
ans = i - j + 1
x = i
y = j
else :
ans = i - j + 1
x = i
y = j
index[a[i]] = i + 1
return [x, y]
def findMinOperations(arr, n):
p = findMax(arr, n)
i = p[ 1 ]
j = p[ 0 ]
return 2 * min (i, n - j - 1 ) + max (i, n - j - 1 )
if __name__ = = "__main__" :
arr = [ 1 , 3 , 3 , 5 , 1 , 9 , 4 , 1 ]
N = len (arr)
print (findMinOperations(arr, N))
|
C#
using System;
using System.Collections.Generic;
class pair {
public int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
public class GFG {
static pair findMax( int [] a, int n)
{
Dictionary< int , int > index
= new Dictionary< int , int >();
int ans = 0, x = -1, y = -1;
for ( int i = 0, j = 0; i < n; i++) {
if (index.ContainsKey(a[i])) {
j = Math.Max(index[a[i]], j);
}
if ((i - j + 1) >= ans) {
if ((i - j + 1) == ans) {
if (i == (n - 1) || j == 0) {
ans = i - j + 1;
x = i;
y = j;
}
}
else {
ans = i - j + 1;
x = i;
y = j;
}
}
if (index.ContainsKey(a[i]))
index[a[i]] = i+1;
else
index.Add(a[i], i + 1);
}
return new pair(x, y);
}
public static int findMinOperations( int [] arr, int n)
{
pair p = findMax(arr, n);
int i = p.second;
int j = p.first;
return 2 * Math.Min(i, n - j - 1)
+ Math.Max(i, n - j - 1);
}
public static void Main(String[] args)
{
int [] arr = { 1, 3, 3, 5, 1, 9, 4, 1 };
int N = arr.Length;
Console.Write(findMinOperations(arr, N));
}
}
|
Javascript
<script>
const findMax = (a, n) => {
let index = {};
let ans = 0, x = -1, y = -1;
for (let i = 0, j = 0; i < n; i++) {
j = Math.max(a[i] in index ? index[a[i]] : 0, j);
if ((i - j + 1) >= ans) {
if ((i - j + 1) == ans) {
if (i == (n - 1) || j == 0) {
ans = i - j + 1;
x = i;
y = j;
}
}
else {
ans = i - j + 1;
x = i;
y = j;
}
}
index[a[i]] = i + 1;
}
return [x, y];
}
const findMinOperations = (arr, n) => {
let p = findMax(arr, n);
let i = p[1];
let j = p[0];
return 2 * Math.min(i, n - j - 1)
+ Math.max(i, n - j - 1);
}
let arr = [1, 3, 3, 5, 1, 9, 4, 1];
let N = arr.length;
document.write(findMinOperations(arr, N));
</script>
|
Time Complexity: O(N) Auxiliary Space: O(1)
|