Minimum number of elements which are not part of Increasing or decreasing subsequence in array
Last Updated :
09 Dec, 2022
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++
// C++ program to return minimum number of elements which
// are not part of increasing or decreasing subsequences.
#include<bits/stdc++.h>
#define MAX 102
using namespace std;
// Return minimum number of elements which is not part of
// any of the sequence.
int countMin(int arr[], int dp[MAX][MAX][MAX], int n, int dec,
int inc, int i)
{
// If already calculated, return value.
if (dp[dec][inc][i] != -1)
return dp[dec][inc][i];
// If whole array is traversed.
if (i == n)
return 0;
// calculating by considering element as part of
// decreasing sequence.
if (arr[i] < arr[dec])
dp[dec][inc][i] = countMin(arr, dp, n, i, inc, i + 1);
// calculating by considering element as part of
// increasing sequence.
if (arr[i] > arr[inc])
{
// If cannot be calculated for decreasing sequence.
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = countMin(arr, dp, n, dec, i, i + 1);
// After considering once by decreasing sequence, now try
// for increasing sequence.
else
dp[dec][inc][i] = min(countMin(arr, dp, n, dec, i, i + 1),
dp[dec][inc][i]);
}
// If element cannot be part of any of the sequence.
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = 1 + countMin(arr, dp, n, dec, inc, i + 1);
// After considering element as part of increasing and
// decreasing sequence trying as not part of any of the
// sequence.
else
dp[dec][inc][i] = min(1 + countMin(arr, dp, n, dec, inc, i + 1),
dp[dec][inc][i]);
return dp[dec][inc][i];
}
// Wrapper Function
int wrapper(int arr[], int n)
{
// Adding two number at the end of array, so that
// increasing and decreasing sequence can be made.
// MAX - 2 index is assigned INT_MAX for decreasing sequence
// because/ next number of sequence must be less than it.
// Similarly, for Increasing sequence INT_MIN is assigned to
// MAX - 1 index.
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);
}
// Driven Program
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
// Java program to return minimum number of
// elements which are not part of increasing
// or decreasing subsequences.
import java.util.*;
class GFG
{
static int MAX = 102;
// Return minimum number of elements which is
// not part of any of the sequence.
static int countMin(int arr[], int dp[][][], int n,
int dec, int inc, int i)
{
// If already calculated, return value.
if (dp[dec][inc][i] != -1)
return dp[dec][inc][i];
// If whole array is traversed.
if (i == n)
return 0;
// calculating by considering element as
// part of decreasing sequence.
if (arr[i] < arr[dec])
dp[dec][inc][i] = countMin(arr, dp, n, i,
inc, i + 1);
// calculating by considering element as
// part of increasing sequence.
if (arr[i] > arr[inc])
{
// If cannot be calculated for
// decreasing sequence.
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = countMin(arr, dp, n,
dec, i, i + 1);
// After considering once by decreasing sequence,
// now try for increasing sequence.
else
dp[dec][inc][i] = Math.min(countMin(arr, dp, n,
dec, i, i + 1),
dp[dec][inc][i]);
}
// If element cannot be part of any of the sequence.
if (dp[dec][inc][i] == -1)
dp[dec][inc][i] = 1 + countMin(arr, dp, n,
dec, inc, i + 1);
// After considering element as part of increasing and
// decreasing sequence trying as not part of any of the
// sequence.
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];
}
// Wrapper Function
static int wrapper(int arr[], int n)
{
// Adding two number at the end of array,
// so that increasing and decreasing sequence
// can be made. MAX - 2 index is assigned
// INT_MAX for decreasing sequence because
// next number of sequence must be less than it.
// Similarly, for Increasing sequence INT_MIN
// is assigned to MAX - 1 index.
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);
}
// Driver Code
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));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to return minimum number of elements which
# are not part of increasing or decreasing subsequences.
MAX=102
# Return minimum number of elements which is not part of
# any of the sequence.
def countMin(arr,dp,n,dec,inc,i):
# If already calculated, return value.
if dp[dec][inc][i] != -1:
return dp[dec][inc][i]
# If whole array is traversed.
if i==n:
return 0
# calculating by considering element as part of
# decreasing sequence.
if arr[i]<arr[dec]:
dp[dec][inc][i] = countMin(arr, dp, n, i, inc, i + 1)
# calculating by considering
# element as part of
# increasing sequence.
if arr[i] > arr[inc]:
# If cannot be calculated for
# decreasing sequence.
if dp[dec][inc][i] == -1:
dp[dec][inc][i] = countMin(arr, dp, n, dec, i, i + 1)
# After considering once by
# decreasing sequence, now try
# for increasing sequence.
else:
dp[dec][inc][i] = min(countMin(arr,dp,n,dec,i,i+1),dp[dec][inc][i])
# If element cannot be part
# of any of the sequence.
if dp[dec][inc][i] == -1:
dp[dec][inc][i] = 1 + countMin(arr, dp, n, dec, inc, i + 1)
# After considering element as part of increasing and
# decreasing sequence trying as not part of any of the
# sequence.
else:
dp[dec][inc][i]=min(1+countMin(arr,dp,n,dec,inc,i+1),dp[dec][inc][i])
return dp[dec][inc][i]
# Wrapper Function
def wrapper(arr,n) :
# Adding two number at the end of array, so that
# increasing and decreasing sequence can be made.
# MAX - 2 index is assigned INT_MAX for decreasing sequence
# because/ next number of sequence must be less than it.
# Similarly, for Increasing sequence INT_MIN is assigned to
# MAX - 1 index.
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)
# Driver code
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))
# This code is contributed by sahilshelangia
C#
// C# program to return minimum number of
// elements which are not part of increasing
// or decreasing subsequences.
using System;
class GFG
{
static int MAX = 102;
// Return minimum number of elements
// which is not part of any of the sequence.
static int countMin(int[] arr, int[,,] dp, int n,
int dec, int inc, int i)
{
// If already calculated, return value.
if (dp[dec, inc, i] != -1)
return dp[dec, inc, i];
// If whole array is traversed.
if (i == n)
return 0;
// calculating by considering element
// as part of decreasing sequence.
if (arr[i] < arr[dec])
dp[dec, inc, i] = countMin(arr, dp, n, i,
inc, i + 1);
// calculating by considering element
// as part of increasing sequence.
if (arr[i] > arr[inc])
{
// If cannot be calculated for
// decreasing sequence.
if (dp[dec, inc, i] == -1)
dp[dec, inc, i] = countMin(arr, dp, n,
dec, i, i + 1);
// After considering once by decreasing
// sequence, now try for increasing sequence.
else
dp[dec, inc, i] = Math.Min(countMin(arr, dp, n,
dec, i, i + 1),
dp[dec, inc, i]);
}
// If element cannot be part of any of the sequence.
if (dp[dec, inc, i] == -1)
dp[dec, inc, i] = 1 + countMin(arr, dp, n, dec,
inc, i + 1);
// After considering element as part of
// increasing and decreasing sequence
// trying as not part of any of the
// sequence.
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];
}
// Wrapper Function
static int wrapper(int[] arr, int n)
{
// Adding two number at the end of array,
// so that increasing and decreasing sequence
// can be made. MAX - 2 index is assigned
// INT_MAX for decreasing sequence because next
// number of sequence must be less than it.
// Similarly, for Increasing sequence INT_MIN
// is assigned to MAX - 1 index.
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);
}
// Driver Code
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));
}
}
// This code is contributed by DrRoot_
JavaScript
<script>
// JavaScript program to return minimum number of elements which
// are not part of increasing or decreasing subsequences.
const MAX=102
// Return minimum number of elements which is not part of
// any of the sequence.
function countMin(arr,dp,n,dec,inc,i){
// If already calculated, return value.
if(dp[dec][inc][i] != -1)
return dp[dec][inc][i]
// If whole array is traversed.
if(i==n)
return 0
// calculating by considering element as part of
// decreasing sequence.
if(arr[i]<arr[dec])
dp[dec][inc][i] = countMin(arr, dp, n, i, inc, i + 1)
// calculating by considering
// element as part of
// increasing sequence.
if(arr[i] > arr[inc])
// If cannot be calculated for
// decreasing sequence.
if(dp[dec][inc][i] == -1)
dp[dec][inc][i] = countMin(arr, dp, n, dec, i, i + 1)
// After considering once by
// decreasing sequence, now try
// for increasing sequence.
else
dp[dec][inc][i] = Math.min(countMin(arr,dp,n,dec,i,i+1),dp[dec][inc][i])
// If element cannot be part
// of any of the sequence.
if(dp[dec][inc][i] == -1)
dp[dec][inc][i] = 1 + countMin(arr, dp, n, dec, inc, i + 1)
// After considering element as part of increasing and
// decreasing sequence trying as not part of any of the
// sequence.
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]
}
// Wrapper Function
function wrapper(arr,n){
// Adding two number at the end of array, so that
// increasing and decreasing sequence can be made.
// MAX - 2 index is assigned INT_MAX for decreasing sequence
// because/ next number of sequence must be less than it.
// Similarly, for Increasing sequence INT_MIN is assigned to
// MAX - 1 index.
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)
}
// Driver code
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))
// This code is contributed by shinjanpatra
</script>
Time Complexity : O(n3)
Auxiliary Space: O(MAX3), here MAX = 102
Similar Reads
Split an array into minimum number of non-increasing or non-decreasing subarrays Given an array arr[] of size N, the task is to split the given array into a minimum number of subarrays such that elements of each subarray are either in non-increasing order or non-decreasing order. Examples: Input: arr[] = {2, 3, 9, 5, 4, 6, 8}Output: 3Explanation: Split the array into 3 subarrays
10 min read
Maximize sum of all elements which are not a part of the Longest Increasing Subsequence Given an array arr[], the task is to find the maximum sum of all the elements which are not a part of the longest increasing subsequence. Examples: Input: arr[] = {4, 6, 1, 2, 3, 8} Output: 10 Explanation: Elements are 4 and 6 Input: arr[] = {5, 4, 3, 2, 1} Output: 14 Explanation: Elements are 5, 4,
8 min read
Count number of Subsequences in Array in which X and Y are min and max elements Given an array arr[] consisting of N unique elements, the task is to return the count of the subsequences in an array in which the minimum element is X and the maximum element is Y. Examples: Input: arr[] = {2, 4, 6, 7, 5}, X = 2, Y = 5Output: 2Explanation: Subsequences in which the minimum element
11 min read
Minimum in an array which is first decreasing then increasing Given an array of N integers where array elements form a strictly decreasing and increasing sequence. The task is to find the smallest number in such an array. Constraints: N >= 3 Examples: Input: a[] = {2, 1, 2, 3, 4}Output: 1Input: a[] = {8, 5, 4, 3, 4, 10}Output: 3 A naive approach is to linea
12 min read
Minimize the number of strictly increasing subsequences in an array | Set 2 Given an array arr[] of size N, the task is to print the minimum possible count of strictly increasing subsequences present in the array. Note: It is possible to swap the pairs of array elements. Examples: Input: arr[] = {2, 1, 2, 1, 4, 3}Output: 2Explanation: Sorting the array modifies the array to
6 min read