Find minimum possible size of array with given rules for removing elements
Last Updated :
11 Mar, 2024
Given an array of numbers and a constant k, minimize size of array with following rules for removing elements.
- Exactly three elements can be removed at one go.
- The removed three elements must be adjacent in array, i.e., arr[i], arr[i+1], arr[i+2]. And the second element must be k greater than first and third element must be k greater than second, i.e., arr[i+1] - arr[i] = k and arr[i+2]-arr[i+1] = k.
Example:
Input: arr[] = {2, 3, 4, 5, 6, 4}, k = 1
Output: 0
We can actually remove all elements.
First remove 4, 5, 6 => We get {2, 3, 4}
Now remove 2, 3, 4 => We get empty array {}
Input: arr[] = {2, 3, 4, 7, 6, 4}, k = 1
Output: 3
We can only remove 2 3 4
We strongly recommend you to minimize your browser and try this yourself first.
For every element arr[i] there are two possibilities.
1) Either the element is not removed.
2) OR element is removed (if it follows rules of removal). When an element is removed, there are again two possibilities.
.....a) It may be removed directly, i.e., initial arr[i+1] is arr[i]+k and arr[i+2] is arr[i] + 2*k.
.....b) There exist x and y such that arr[x] - arr[i] = k, arr[y] - arr[x] = k, and subarrays "arr[i+1...x-1]" & "arr[x+1...y-1]" can be completely removed.
Below is recursive algorithm based on above idea.
// Returns size of minimum possible size of arr[low..high]
// after removing elements according to given rules
findMinSize(arr[], low, high, k)
// If there are less than 3 elements in arr[low..high]
1) If high-low+1 < 3, return high-low+1
// Consider the case when 'arr[low]' is not considered as
// part of any triplet to be removed. Initialize result
// using this case
2) result = 1 + findMinSize(arr, low+1, high)
// Case when 'arr[low]' is part of some triplet and removed
// Try all possible triplets that have arr[low]
3) For all i from low+1 to high
For all j from i+1 to high
Update result if all of the following conditions are met
a) arr[i] - arr[low] = k
b) arr[j] - arr[i] = k
c) findMinSize(arr, low+1, i-1, k) returns 0
d) findMinSize(arr, i+1, j-1, k) also returns 0
e) Result calculated for this triplet (low, i, j)
is smaller than existing result.
4) Return result
The time complexity of above solution is exponential. If we draw the complete recursion tree, we can observer that many subproblems are solved again and again. Since same subproblems are called again, this problem has Overlapping Subproblems property. Like other typical Dynamic Programming(DP) problems, recomputations of same subproblems can be avoided by constructing a temporary array dp[][] to store results of the subproblems. Below is Dynamic Programming based solution
Below is the implementation of above idea. The implementation is memoization based, i.e., it is recursive and uses a lookup table dp[][] to check if a subproblem is already solved or not.
C++
// C++ program to find size of minimum possible array after
// removing elements according to given rules
#include <bits/stdc++.h>
using namespace std;
#define MAX 1000
// dp[i][j] denotes the minimum number of elements left in
// the subarray arr[i..j].
int dp[MAX][MAX];
int minSizeRec(int arr[], int low, int high, int k)
{
// If already evaluated
if (dp[low][high] != -1)
return dp[low][high];
// If size of array is less than 3
if ( (high-low + 1) < 3)
return high-low +1;
// Initialize result as the case when first element is
// separated (not removed using given rules)
int res = 1 + minSizeRec(arr, low+1, high, k);
// Now consider all cases when first element forms a triplet
// and removed. Check for all possible triplets (low, i, j)
for (int i = low+1; i<=high-1; i++)
{
for (int j = i+1; j <= high; j++ )
{
// Check if this triplet follows the given rules of
// removal. And elements between 'low' and 'i' , and
// between 'i' and 'j' can be recursively removed.
if (arr[i] == (arr[low] + k) &&
arr[j] == (arr[low] + 2*k) &&
minSizeRec(arr, low+1, i-1, k) == 0 &&
minSizeRec(arr, i+1, j-1, k) == 0)
{
res = min(res, minSizeRec(arr, j+1, high, k));
}
}
}
// Insert value in table and return result
return (dp[low][high] = res);
}
// This function mainly initializes dp table and calls
// recursive function minSizeRec
int minSize(int arr[], int n, int k)
{
memset(dp, -1, sizeof(dp));
return minSizeRec(arr, 0, n-1, k);
}
// Driver program to test above function
int main()
{
int arr[] = {2, 3, 4, 5, 6, 4};
int n = sizeof(arr)/sizeof(arr[0]);
int k = 1;
cout << minSize(arr, n, k) << endl;
return 0;
}
Java
// Java program to find size of
// minimum possible array after
// removing elements according
// to given rules
class GFG
{
static int MAX = 1000;
// dp[i][j] denotes the minimum
// number of elements left in
// the subarray arr[i..j].
static int dp[][] = new int[MAX][MAX];
static int minSizeRec(int arr[], int low,
int high, int k)
{
// If already evaluated
if (dp[low][high] != -1)
{
return dp[low][high];
}
// If size of array is less than 3
if ((high - low + 1) < 3)
{
return high - low + 1;
}
// Initialize result as the
// case when first element is
// separated (not removed
// using given rules)
int res = 1 + minSizeRec(arr,
low + 1, high, k);
// Now consider all cases when
// first element forms a triplet
// and removed. Check for all
// possible triplets (low, i, j)
for (int i = low + 1; i <= high - 1; i++)
{
for (int j = i + 1; j <= high; j++)
{
// Check if this triplet
// follows the given rules of
// removal. And elements
// between 'low' and 'i' , and
// between 'i' and 'j' can
// be recursively removed.
if (arr[i] == (arr[low] + k) &&
arr[j] == (arr[low] + 2 * k) &&
minSizeRec(arr, low + 1, i - 1, k) == 0 &&
minSizeRec(arr, i + 1, j - 1, k) == 0)
{
res = Math.min(res, minSizeRec(arr, j + 1, high, k));
}
}
}
// Insert value in table and return result
return (dp[low][high] = res);
}
// This function mainly initializes
// dp table and calls recursive
// function minSizeRec
static int minSize(int arr[], int n, int k)
{
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
dp[i][j] = -1;
}
}
return minSizeRec(arr, 0, n - 1, k);
}
// Driver code
public static void main(String[] args)
{
int arr[] = {2, 3, 4, 5, 6, 4};
int n = arr.length;
int k = 1;
System.out.println(minSize(arr, n, k));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to find size of
# minimum possible array after
# removing elements according to given rules
MAX=1000
dp=[[-1 for i in range(MAX)] for i in range(MAX)]
# dp[i][j] denotes the minimum number of elements left in
# the subarray arr[i..j].
def minSizeRec(arr,low,high,k):
# If already evaluated
if dp[low][high] != -1:
return dp[low][high]
# If size of array is less than 3
if (high-low + 1) < 3:
return (high-low + 1)
# Initialize result as the case when first element is
# separated (not removed using given rules)
res = 1 + minSizeRec(arr, low+1, high, k)
# Now consider all cases when
# first element forms a triplet
# and removed. Check for all possible
# triplets (low, i, j)
for i in range(low+1,high):
for j in range(i+1,high+1):
# Check if this triplet follows the given rules of
# removal. And elements between 'low' and 'i' , and
# between 'i' and 'j' can be recursively removed.
if (arr[i]==(arr[low]+k) and arr[j] == (arr[low] + 2*k) and
minSizeRec(arr, low+1, i-1, k) == 0 and
minSizeRec(arr, i+1, j-1, k) == 0):
res=min(res,minSizeRec(arr,j+1,high,k) )
# Insert value in table and return result
dp[low][high] = res
return res
# This function mainly initializes dp table and calls
# recursive function minSizeRec
def minSize(arr,n,k):
dp=[[-1 for i in range(MAX)] for i in range(MAX)]
return minSizeRec(arr, 0, n-1, k)
# Driver program to test above function
if __name__=='__main__':
arr=[2, 3, 4, 5, 6, 4]
n=len(arr)
k=1
print(minSize(arr,n,k))
# this code is contributed by sahilshelangia
C#
// C# program to find size of
// minimum possible array after
// removing elements according
// to given rules
using System;
class GFG
{
static int MAX = 1000;
// dp[i,j] denotes the minimum
// number of elements left in
// the subarray arr[i..j].
static int [,]dp = new int[MAX, MAX];
static int minSizeRec(int []arr, int low,
int high, int k)
{
// If already evaluated
if (dp[low, high] != -1)
{
return dp[low, high];
}
// If size of array is less than 3
if ((high - low + 1) < 3)
{
return high - low + 1;
}
// Initialize result as the
// case when first element is
// separated (not removed
// using given rules)
int res = 1 + minSizeRec(arr,
low + 1, high, k);
// Now consider all cases when
// first element forms a triplet
// and removed. Check for all
// possible triplets (low, i, j)
for (int i = low + 1; i <= high - 1; i++)
{
for (int j = i + 1; j <= high; j++)
{
// Check if this triplet
// follows the given rules of
// removal. And elements
// between 'low' and 'i' , and
// between 'i' and 'j' can
// be recursively removed.
if (arr[i] == (arr[low] + k) &&
arr[j] == (arr[low] + 2 * k) &&
minSizeRec(arr, low + 1, i - 1, k) == 0 &&
minSizeRec(arr, i + 1, j - 1, k) == 0)
{
res = Math.Min(res, minSizeRec(arr, j + 1, high, k));
}
}
}
// Insert value in table and return result
return (dp[low, high] = res);
}
// This function mainly initializes
// dp table and calls recursive
// function minSizeRec
static int minSize(int []arr, int n, int k)
{
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
dp[i, j] = -1;
}
}
return minSizeRec(arr, 0, n - 1, k);
}
// Driver code
public static void Main(String[] args)
{
int []arr = {2, 3, 4, 5, 6, 4};
int n = arr.Length;
int k = 1;
Console.WriteLine(minSize(arr, n, k));
}
}
// This code contributed by Rajput-Ji
JavaScript
<script>
// Javascript program to find size of
// minimum possible array after
// removing elements according
// to given rules
let MAX = 1000;
// dp[i][j] denotes the minimum
// number of elements left in
// the subarray arr[i..j].
let dp = new Array(MAX);
for(let i = 0; i < MAX; i++)
{
dp[i] = new Array(MAX);
for(let j = 0; j < MAX; j++)
{
dp[i][j] = 0;
}
}
function minSizeRec(arr, low, high, k)
{
// If already evaluated
if (dp[low][high] != -1)
{
return dp[low][high];
}
// If size of array is less than 3
if ((high - low + 1) < 3)
{
return high - low + 1;
}
// Initialize result as the
// case when first element is
// separated (not removed
// using given rules)
let res = 1 + minSizeRec(arr, low + 1, high, k);
// Now consider all cases when
// first element forms a triplet
// and removed. Check for all
// possible triplets (low, i, j)
for (let i = low + 1; i <= high - 1; i++)
{
for (let j = i + 1; j <= high; j++)
{
// Check if this triplet
// follows the given rules of
// removal. And elements
// between 'low' and 'i' , and
// between 'i' and 'j' can
// be recursively removed.
if (arr[i] == (arr[low] + k) &&
arr[j] == (arr[low] + 2 * k) &&
minSizeRec(arr, low + 1, i - 1, k) == 0 &&
minSizeRec(arr, i + 1, j - 1, k) == 0)
{
res = Math.min(res, minSizeRec(arr, j + 1, high, k));
}
}
}
// Insert value in table and return result
return (dp[low][high] = res);
}
// This function mainly initializes
// dp table and calls recursive
// function minSizeRec
function minSize(arr, n, k)
{
for (let i = 0; i < MAX; i++)
{
for (let j = 0; j < MAX; j++)
{
dp[i][j] = -1;
}
}
return minSizeRec(arr, 0, n - 1, k);
}
let arr = [2, 3, 4, 5, 6, 4];
let n = arr.length;
let k = 1;
document.write(minSize(arr, n, k));
// This code is contributed by mukesh07.
</script>
Output:
0
Similar Reads
Minimum removal of elements from end of an array required to obtain sum K
Given an integer K and an array A[] of size N, the task is to create a new array with sum K with minimum number of operations, where in each operation, an element can be removed either from the start or end of A[] and appended to the new array. If it is not possible to generate a new array with sum
15+ min read
Find the element having maximum premutiples in the array
Given an array arr[], the task is to find the element which has the maximum number of pre-multiples present in the set. For any index i, pre-multiple is the number that is multiple of i and is present before the ith index of the array. Also, print the count of maximum multiples of that element in th
8 min read
Find the minimum value of K required to remove all elements from the array in at most M operations
Given array A[] of size N and integer M, Perform the following operation until the array becomes empty. Choose K and the pick first K elements of array A[]. In one operation subtract all these chosen K elements by 1 if any element becomes zero that element will be deleted and it will be replaced by
13 min read
Find position of the leader element in given Array with given operations
Given an array arr[]. The task is to find the position of the leader element in arr[]. The leader element is the one, which can remove all other elements in the array using the below operations. If arr[i] > arr[i + 1], It removes the (i+1)th element and increment their value by 1 and decrease the
7 min read
Find the position of the last removed element from the array
Given an array of size N and an integer M . Perform the following operations on the given array: If a[i] > M then push a[i] - M to end of the array, otherwise remove it from the array.Perform the first operation while the array is non-empty. The task is to find the original position of the elemen
6 min read
Minimize the sum of MEX by removing all elements of array
Given an array of integers arr[] of size N. You can perform the following operation N times: Pick any index i, and remove arr[i] from the array and add MEX(arr[]) i.e., Minimum Excluded of the array arr[] to your total score. Your task is to minimize the total score. Examples: Input: N = 8, arr[] =
7 min read
Minimum operations of given type required to empty given array
Given an array arr[] of size N, the task is to find the total count of operations required to remove all the array elements such that if the first element of the array is the smallest element, then remove that element, otherwise move the first element to the end of the array. Examples: Input: A[] =
14 min read
Minimum sum possible by removing all occurrences of any array element
Given an array arr[] consisting of N integers, the task is to find the minimum possible sum of the array by removing all occurrences of any single array element. Examples: Input: N = 4, arr[] = {4, 5, 6, 6}Output: 9Explanation: All distinct array elements are {4, 5, 6}. Removing all occurrences of 4
6 min read
Minimize operations of removing 2i -1 array elements to empty given array
Given an array arr[] of size N, the task is to empty given array by removing 2i - 1 array elements in each operation (i is any positive integer). Find the minimum number of operations required. Examples: Input: arr[] = { 2, 3, 4 } Output: 1 Explanation: Removing (22 - 1) elements i.e { arr[0], arr[1
5 min read
Minimum bitwise OR after removing at most K elements from given Array
Given an array A[] of length N, the task is to find the minimum possible value of bitwise OR of the elements after removing at most K elements. Examples: Input: A = {1, 10, 9, 4, 5, 16, 8}, K = 3Output: 11Explanation: Remove 4, 5, 16 for the given array.The remaining elements are {1, 10, 9, 5}. The
7 min read