Given an array X[] of length N and an integer K. Then your task is to output minimum length of X[] after removing at most K number of sub-arrays, which satisfies the following conditions:
- Size of the sub-array must be greater than 1.
- First and last element of sub-array must be same.
Note: The sub-arrays which will satisfy the above condition will be non-intersecting. Formally, any sub-array which starts and ends with element A will not be overlapped with the any sub-array starting and ending with the element except A.
Examples:
Input: N = 9, X[] = {2, 3, 1, 1, 9, 34, 56, 9, 9}, K = 3
Output: 2
Explanation: There are two sub-arrays {1, 1} and {9, 34, 56, 9, 9}, which start and end with same element having size greater than 1. Since we can remove at most K = 3 sub-arrays, but two of such kind are present. Therefore, after removing these two sub-arrays, the minimum length of the remained X[] will be = 2.Input: N = 4, X[] = {1, 2, 3, 4}, X = 2
Output: 4
Explanation: There are no sub-arrays such that it follows the given conditions. Therefore, we can’t remove any such sub-array. Hence the minimum length of X[] will be original as initial 4.
Approach: The problem can be solved by applying the Greedy approach.
We have to remove the K number of sub-arrays such that they follow the given conditions. As it is mentioned that sub-arrays must start and end with the same element. Thus we can get the first and last occurrence of an element from X[]. If the size of such sub-arrays is greater than 1 then store that length in a separate list. We can find the length of all such sub-arrays by iterating over X[] using a loop. After finding the length of all such sub-arrays, Sort them in any order(descending or ascending), and remove K number of subarrays of the biggest length from N, Formally, for minimizing the length of the remaining X[], we must remove the K sub-arrays having a maximum length. Now, the length of the remained X[] will be the minimum possible.
Below are the steps for the above approach:
- Create an ArrayList say list and copy the element of X[] into it.
- Create a HashMap say map for storing the length of sub-arrays.
-
Run a loop from i = 0 to i < list size,
- Initialize a variable firstIndex = IndexOf(current_element)
- Initialize a variable lastIndex = lastIndexOf(current_element)
-
Check if(firstIndex == lastIndex)
- continue
-
else if the size is greater than 1, then put the length in Map
- map.put(current_element, lastIndex-firstIndex+1)
- Create an ArrayList say length for storing frequencies from the map.
- Sort the array length.
-
Iterate the length array from index i = size of length array to i ≥ 0 and k > 0 and subtract K biggest lengths from N,
N = N – lengths.get(i) and decrement the value of K by 1. - Print the value of N.
Below is the code for the above approach:
#include <bits/stdc++.h> using namespace std;
// Method for printing minimum length void remainedElements( int N, int K, vector< int >& X)
{ // Map initialized for storing
// lentgth of sub subarrays along
// with the element
unordered_map< int , int > map;
// Loop for initilizing map with
// length of such sub-arrays
for ( int i = 0; i < X.size(); i++) {
// Getting first index of
// current element
int firstIndex = find(X.begin(), X.end(), X[i]) - X.begin();
// Getting last index of
// current element
int lastIndex = find(X.rbegin(), X.rend(), X[i]) - X.rbegin();
// Convert last index to
// actual index in X
lastIndex = X.size() - 1 - lastIndex;
// If firstIndex is equal to
// Last index Formally, there
// is only one element of such
// value Then ignore it, can't
// be considered as sub-array
// because size must be
// greater than 1
if (firstIndex == lastIndex) {
continue ;
}
// If size is greater than 1,
// Then putting length in Map
else {
map[X[i]] = lastIndex - firstIndex + 1;
}
}
// Vector for storing lengths
// from map
vector< int > lengths;
for ( auto it = map.begin(); it != map.end(); ++it) {
lengths.push_back(it->second);
}
// Sorting sub-array's length
sort(lengths.begin(), lengths.end());
// Removing K number of such
// sub-arrays with biggest size
// formally, Iterating backward
// in list of sorted lengths
for ( int i = lengths.size() - 1; i >= 0 && K > 0;
i--) {
N -= lengths[i];
K--;
}
// Printing minimum length after
// removing such K sub-arrays
cout << N << endl;
} // Driver Function int main()
{ // Inputs
int N = 9;
int K = 3;
vector< int > X = { 12, 3, 1, 1, 2, 2, 2, 2, 5 };
// Function call for printing
// length after removing such
// K number of sub-arrays
remainedElements(N, K, X);
return 0;
} |
// java code to implement the approach import java.util.*;
public class GFG {
// Driver Function
public static void main(String[] args)
{
// Inputs
int N = 9 ;
int K = 3 ;
int X[] = { 12 , 3 , 1 , 1 , 2 , 2 , 2 , 2 , 5 };
// Function call for printing
// length after removing such
// K number of sub-arrays
RemainedElements(N, K, X);
}
// Method for printing minimum length
static void RemainedElements( int N, int K, int [] X)
{
// ArrayList for storing element
// of X[] because it will be
// convienient to find First and
// last index of an element using
// in-built func. such as
// indexOf(), lastIndexOf()
ArrayList<Integer> list = new ArrayList<>();
// Loop for copying elements
// from X[] to list
for ( int x : X)
list.add(x);
// Map initialized for storing
// lentgth of sub subarrays along
// with the element
HashMap<Integer, Integer> map = new HashMap<>();
// Loop for initilizing map with
// length of such sub-arrays
for ( int i = 0 ; i < list.size(); i++) {
// Getting first index of
// current element
int firstIndex = list.indexOf(list.get(i));
// Getting last index of
// current element
int lastIndex = list.lastIndexOf(list.get(i));
// If firstIndex is equal to
// Last index Formally, there
// is only one element of such
// value Then ignore it, can't
// be considered as sub-array
// because size must be
// greater than 1
if (firstIndex == lastIndex) {
continue ;
}
// If size is greater than 1,
// Then putting length in Map
else {
map.put(list.get(i),
lastIndex - firstIndex + 1 );
}
}
// List for storing lengths
// from map
ArrayList<Integer> lengths
= new ArrayList<>(map.values());
// Sorting sub-array's length
lengths.sort( null );
// Removing K number of such
// sub-arrays with biggest size
// formally, Iterating backward
// in list of sorted lengths
for ( int i = lengths.size() - 1 ; i >= 0 && K > 0 ;
i--) {
N = N - lengths.get(i);
K--;
}
// Printing minimum length after
// removing such K sub-arrays
System.out.println(N);
}
} |
import collections
# Method for printing minimum length def remainedElements(N, K, X):
# Map initialized for storing
# lentgth of sub subarrays along
# with the element
map = collections.defaultdict( int )
# Loop for initilizing map with
# length of such sub-arrays
for i in range ( len (X)):
# Getting first index of
# current element
firstIndex = X.index(X[i])
# Getting last index of
# current element
lastIndex = len (X) - 1 - X[:: - 1 ].index(X[i])
# If firstIndex is equal to
# Last index Formally, there
# is only one element of such
# value Then ignore it, can't
# be considered as sub-array
# because size must be
# greater than 1
if firstIndex = = lastIndex:
continue
# If size is greater than 1,
# Then putting length in Map
else :
map [X[i]] = lastIndex - firstIndex + 1
# Vector for storing lengths
# from map
lengths = list ( map .values())
# sorting sub-array's length
lengths.sort()
# Removing K number of such
# sub-arrays with biggest size
# formally, Iterating backward
# in list of sorted lengths
for i in range ( len (lengths) - 1 , - 1 , - 1 ):
N - = lengths[i]
K - = 1
if K = = 0 :
break
# Printing minimum length after
# removing such K sub-arrays
print (N)
# Driver Function N = 9
K = 3
X = [ 12 , 3 , 1 , 1 , 2 , 2 , 2 , 2 , 5 ]
remainedElements(N, K, X) |
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{ // Method for printing minimum length
static void RemainedElements( int N, int K, List< int > X)
{
// Dictionary initialized for storing
// length of sub subarrays along with the element
Dictionary< int , int > map = new Dictionary< int , int >();
// Loop for initializing map with
// the length of such sub-arrays
for ( int i = 0; i < X.Count; i++)
{
// Getting first index of current element
int firstIndex = X.IndexOf(X[i]);
// Getting last index of current element
int lastIndex = X.LastIndexOf(X[i]);
// If firstIndex is equal to
// last index, there is only one element of such value
// Then ignore it, it can't be considered as sub-array
// because size must be greater than 1
if (firstIndex == lastIndex)
{
continue ;
}
// If size is greater than 1,
// then put length in the map
else
{
map[X[i]] = lastIndex - firstIndex + 1;
}
}
// List for storing lengths from map
List< int > lengths = new List< int >();
foreach ( var kvp in map)
{
lengths.Add(kvp.Value);
}
// Sorting sub-array's length
lengths.Sort();
// Removing K number of such sub-arrays with the biggest size
// Formally, iterating backward in the list of sorted lengths
for ( int i = lengths.Count - 1; i >= 0 && K > 0; i--)
{
N -= lengths[i];
K--;
}
// Printing the minimum length after removing such K sub-arrays
Console.WriteLine(N);
}
// Driver Function
public static void Main()
{
// Inputs
int N = 9;
int K = 3;
List< int > X = new List< int > { 12, 3, 1, 1, 2, 2, 2, 2, 5 };
// Function call for printing
// length after removing such
// K number of sub-arrays
RemainedElements(N, K, X);
}
} |
function GFG(N, K, X) {
// Map initialized for storing the length of sub-arrays along with
// the element
const map = new Map();
// Loop for initializing the map with
// the length of sub-arrays
for (let i = 0; i < X.length; i++) {
// Getting the first index of current element
const firstIndex = X.indexOf(X[i]);
// Getting the last index of current element
const lastIndex = X.lastIndexOf(X[i]);
// If firstIndex is equal to the last index
// ignore it (size must be greater than 1)
if (firstIndex === lastIndex) {
continue ;
} else {
// Calculate the length and store it in the map
map.set(X[i], lastIndex - firstIndex + 1);
}
}
// Get an array of sub-array lengths from the map
const lengths = Array.from(map.values());
// Sort the sub-array lengths
lengths.sort((a, b) => a - b);
// Removing K number of sub-arrays with biggest size
for (let i = lengths.length - 1; i >= 0 && K > 0; i--) {
N -= lengths[i];
K--;
}
// Printing the minimum length after removing K sub-arrays
console.log(N);
} // Driver Function function main() {
// Inputs
const N = 9;
const K = 3;
const X = [12, 3, 1, 1, 2, 2, 2, 2, 5];
// Function call for calculating the minimum length after
// removing K sub-arrays
GFG(N, K, X);
} main(); |
3
Time Complexity: O(N * LogN)
Space Complexity: O(N)