Minimum number of elements which are not part of Increasing or decreasing subsequence in array
Given an array of n elements. Make strictly increasing and strictly decreasing subsequences from the array such that each array element belongs to increasing subsequence or decreasing subsequence, but not both, or can be part of none of the subsequence. Minimize the number of elements which are not part of any of the subsequences and find the count of such elements.
Examples:
Input : arr[] = { 7, 8, 1, 2, 4, 6, 3, 5, 2, 1, 8, 7 }
Output : 2
Increasing sequence can be { 1, 2, 4, 5, 8 }.
Decreasing sequence can be { 7, 6, 3, 2, 1 }.
So, only 2 (8, 7) element is left which are not part of
either of the subsequences.
Input : arr[] = { 1, 4, 2, 3, 3, 2, 4, 1 }
Output : 0
Increasing sequence can be { 1, 2, 3, 4 }.
Decreasing sequence can be { 4, 3, 2, 1 }.
So, no element is left which is not part of either of
the subsequences.
The idea is to make a decision on each index, starting from index 0, one by one. For each index there can be three possibilities, first, it can belong to increasing sequence, second, it can belong to decreasing sequence, third, it does not belong to any of these sequences. So, for each index, check for the optimal answer (minimum element which is not part of any of the subsequences) by considering it once as a part of increasing subsequence or as a part of decreasing subsequence. If the optimal answer cannot be achieved by them then leave it as the element which is not part of any of the sequence. To decrease the complexity (using Dynamic Programming), we can store the number of elements which are not part of any of the subsequences using 3D array dp[x][y][z], where x indicates the decision index, y indicates the last index of decreasing sequence, z indicates the last index of increasing sequence.
Below is the implementation of this approach:
C++
#include<bits/stdc++.h>
#define MAX 102
using namespace std;
int countMin( int arr[], int dp[MAX][MAX][MAX], int n, int dec,
int inc, int i)
{
if (dp[dec][inc][i] != -1)
return dp[dec][inc][i];
if (i == n)
return 0;
if (arr[i] < arr[dec])
dp[dec][inc][i] = countMin(arr, dp, n, i, inc, i + 1);
if (arr[i] > arr[inc])
{
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = countMin(arr, dp, n, dec, i, i + 1);
else
dp[dec][inc][i] = min(countMin(arr, dp, n, dec, i, i + 1),
dp[dec][inc][i]);
}
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = 1 + countMin(arr, dp, n, dec, inc, i + 1);
else
dp[dec][inc][i] = min(1 + countMin(arr, dp, n, dec, inc, i + 1),
dp[dec][inc][i]);
return dp[dec][inc][i];
}
int wrapper( int arr[], int n)
{
arr[MAX - 2] = INT_MAX;
arr[MAX - 1] = INT_MIN;
int dp[MAX][MAX][MAX];
memset (dp, -1, sizeof dp);
return countMin(arr, dp, n, MAX - 2, MAX - 1, 0);
}
int main()
{
int n = 12;
int arr[MAX] = { 7, 8, 1, 2, 4, 6, 3, 5, 2, 1, 8, 7 };
cout << wrapper(arr, n) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MAX = 102 ;
static int countMin( int arr[], int dp[][][], int n,
int dec, int inc, int i)
{
if (dp[dec][inc][i] != - 1 )
return dp[dec][inc][i];
if (i == n)
return 0 ;
if (arr[i] < arr[dec])
dp[dec][inc][i] = countMin(arr, dp, n, i,
inc, i + 1 );
if (arr[i] > arr[inc])
{
if (dp[dec][inc][i] == - 1 )
dp[dec][inc][i] = countMin(arr, dp, n,
dec, i, i + 1 );
else
dp[dec][inc][i] = Math.min(countMin(arr, dp, n,
dec, i, i + 1 ),
dp[dec][inc][i]);
}
if (dp[dec][inc][i] == - 1 )
dp[dec][inc][i] = 1 + countMin(arr, dp, n,
dec, inc, i + 1 );
else
dp[dec][inc][i] = Math.min( 1 + countMin(arr, dp, n,
dec, inc, i + 1 ),
dp[dec][inc][i]);
return dp[dec][inc][i];
}
static int wrapper( int arr[], int n)
{
arr[MAX - 2 ] = Integer.MAX_VALUE;
arr[MAX - 1 ] = Integer.MIN_VALUE;
int [][][]dp = new int [MAX][MAX][MAX];
for ( int i = 0 ; i < MAX; i++)
{
for ( int j = 0 ; j < MAX; j++)
{
for ( int l = 0 ; l < MAX; l++)
dp[i][j][l] = - 1 ;
}
}
return countMin(arr, dp, n, MAX - 2 ,
MAX - 1 , 0 );
}
public static void main(String[] args)
{
int n = 12 ;
int [] arr = new int [MAX];
arr[ 0 ] = 7 ;
arr[ 1 ] = 8 ;
arr[ 2 ] = 1 ;
arr[ 3 ] = 2 ;
arr[ 4 ] = 4 ;
arr[ 5 ] = 6 ;
arr[ 6 ] = 3 ;
arr[ 7 ] = 5 ;
arr[ 8 ] = 2 ;
arr[ 9 ] = 1 ;
arr[ 10 ] = 8 ;
arr[ 11 ] = 7 ;
System.out.println(wrapper(arr, n));
}
}
|
Python3
MAX = 102
def countMin(arr,dp,n,dec,inc,i):
if dp[dec][inc][i] ! = - 1 :
return dp[dec][inc][i]
if i = = n:
return 0
if arr[i]<arr[dec]:
dp[dec][inc][i] = countMin(arr, dp, n, i, inc, i + 1 )
if arr[i] > arr[inc]:
if dp[dec][inc][i] = = - 1 :
dp[dec][inc][i] = countMin(arr, dp, n, dec, i, i + 1 )
else :
dp[dec][inc][i] = min (countMin(arr,dp,n,dec,i,i + 1 ),dp[dec][inc][i])
if dp[dec][inc][i] = = - 1 :
dp[dec][inc][i] = 1 + countMin(arr, dp, n, dec, inc, i + 1 )
else :
dp[dec][inc][i] = min ( 1 + countMin(arr,dp,n,dec,inc,i + 1 ),dp[dec][inc][i])
return dp[dec][inc][i]
def wrapper(arr,n) :
arr[ MAX - 2 ] = 1000000000
arr[ MAX - 1 ] = - 1000000000
dp = [[[ - 1 for i in range ( MAX )] for i in range ( MAX )] for i in range ( MAX )]
return countMin(arr,dp,n, MAX - 2 , MAX - 1 , 0 )
if __name__ = = '__main__' :
n = 12
arr = [ 7 , 8 , 1 , 2 , 4 , 6 , 3 , 5 , 2 , 1 , 8 , 7 ]
for i in range ( MAX ):
arr.append( 0 )
print (wrapper(arr,n))
|
C#
using System;
class GFG
{
static int MAX = 102;
static int countMin( int [] arr, int [,,] dp, int n,
int dec, int inc, int i)
{
if (dp[dec, inc, i] != -1)
return dp[dec, inc, i];
if (i == n)
return 0;
if (arr[i] < arr[dec])
dp[dec, inc, i] = countMin(arr, dp, n, i,
inc, i + 1);
if (arr[i] > arr[inc])
{
if (dp[dec, inc, i] == -1)
dp[dec, inc, i] = countMin(arr, dp, n,
dec, i, i + 1);
else
dp[dec, inc, i] = Math.Min(countMin(arr, dp, n,
dec, i, i + 1),
dp[dec, inc, i]);
}
if (dp[dec, inc, i] == -1)
dp[dec, inc, i] = 1 + countMin(arr, dp, n, dec,
inc, i + 1);
else
dp[dec, inc, i] = Math.Min(1 + countMin(arr, dp, n,
dec, inc, i + 1),
dp[dec, inc, i]);
return dp[dec, inc, i];
}
static int wrapper( int [] arr, int n)
{
arr[MAX - 2] = int .MaxValue;
arr[MAX - 1] = int .MinValue;
int [,,] dp = new int [MAX, MAX, MAX];
for ( int i = 0; i < MAX; i++)
for ( int j = 0; j < MAX; j++)
for ( int k = 0; k < MAX; k++)
dp[i, j, k] = -1;
return countMin(arr, dp, n, MAX - 2,
MAX - 1, 0);
}
static void Main()
{
int n = 12;
int [] arr = new int [MAX];
arr[0] = 7;
arr[1] = 8;
arr[2] = 1;
arr[3] = 2;
arr[4] = 4;
arr[5] = 6;
arr[6] = 3;
arr[7] = 5;
arr[8] = 2;
arr[9] = 1;
arr[10] = 8;
arr[11] = 7;
Console.Write(wrapper(arr, n));
}
}
|
Javascript
<script>
const MAX=102
function countMin(arr,dp,n,dec,inc,i){
if (dp[dec][inc][i] != -1)
return dp[dec][inc][i]
if (i==n)
return 0
if (arr[i]<arr[dec])
dp[dec][inc][i] = countMin(arr, dp, n, i, inc, i + 1)
if (arr[i] > arr[inc])
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = countMin(arr, dp, n, dec, i, i + 1)
else
dp[dec][inc][i] = Math.min(countMin(arr,dp,n,dec,i,i+1),dp[dec][inc][i])
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = 1 + countMin(arr, dp, n, dec, inc, i + 1)
else
dp[dec][inc][i]=Math.min(1+countMin(arr,dp,n,dec,inc,i+1),dp[dec][inc][i])
return dp[dec][inc][i]
}
function wrapper(arr,n){
arr[MAX-2]=1000000000
arr[MAX-1]=-1000000000
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] = new Array(MAX).fill(-1)
}
}
return countMin(arr,dp,n,MAX-2,MAX-1,0)
}
let n=12
let arr=[ 7, 8, 1, 2, 4, 6, 3, 5, 2, 1, 8, 7]
for (let i=0;i<MAX;i++)
arr.push(0)
document.write(wrapper(arr,n))
</script>
|
Time Complexity : O(n3)
Auxiliary Space: O(MAX3), here MAX = 102
Last Updated :
09 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...