Related Articles

# Minimum deletions in Array to make difference of adjacent elements non-decreasing

• Last Updated : 06 Aug, 2021

Given an array A of N non-negative integers, the task is to compute the minimum number of elements to be deleted so, that the following conditions hold:

• The elements are in non-decreasing order. (Formally, for each i (1 ≤ i ≤ N-1), the condition Ai+1 >= Ai  should hold.)
• The difference between adjacent elements should be in non-decreasing order. (Formally, for each i (2 ≤ i ≤ N-1), the condition Ai-Ai-1 ≤ Ai+1-Ai should hold.)

Examples:

Input: A = {1, 4, 5, 7, 20, 21}
Output:
2
Explanation: By deleting 5 and 21, the array {1, 4, 7, 20} is obtained. Here the elements are in non-decreasing order and the difference between adjacent elements are 3, 3, 13 which are in non-decreasing order.

Input: A = {3, 2}
Output
1
Explanation: The original array doesn’t satisfy the first condition. Hence, either of the elements can be deleted to get an array with a single element.

Naive Approach: The naive approach is to generate all subsets of the given array and check whether any of the subsets satisfies the condition. If it does, check how many elements have been deleted to get that subset and, then, take the minimum.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function for finding minimum deletions so that the array``// becomes non decreasing and the difference between adjacent``// elements also becomes non decreasing``int` `minimumDeletions(``int` `A[], ``int` `N)``{``    ``// initialize answer to a large value``    ``int` `ans = INT_MAX;` `    ``// generating all subsets``    ``for` `(``int` `i = 1; i < (1 << N); i++) {``        ``vector<``int``> temp;``        ``for` `(``int` `j = 0; j < N; j++) {``            ``if` `((i & (1 << j)) != 0) {``                ``temp.push_back(A[j]);``            ``}``        ``}``        ``int` `flag = 0;` `        ``// checking the first condition``        ``for` `(``int` `j = 1; j < temp.size(); j++)``            ``if` `(temp[j] < temp[j - 1])``                ``flag = 1;` `        ``// checking the second condition``        ``for` `(``int` `j = 1; j < temp.size() - 1; j++)``            ``if` `(temp[j] - temp[j - 1]``                ``> temp[j + 1] - temp[j])``                ``flag = 1;` `        ``// if both conditions are satisfied consider the``        ``// answer for minimum``        ``if` `(flag == 0) {``            ``ans = min(ans, N - (``int``)temp.size());``        ``}``    ``}``    ``return` `ans;``}``// Driver code``int` `main()``{``    ``// Input``    ``int` `A[] = { 1, 4, 5, 7, 20, 21 };``    ``int` `N = ``sizeof``(A) / ``sizeof``(A);` `    ``// Function call``    ``cout << minimumDeletions(A, N) << endl;` `    ``return` `0;``}`

## Java

 `// Java program for the above approach`  `import` `java.util.ArrayList;`  `class` `GFG{` `// Function for finding minimum deletions so that the array``// becomes non decreasing and the difference between adjacent``// elements also becomes non decreasing``public` `static` `int` `minimumDeletions(``int` `A[], ``int` `N)``{``    ``// initialize answer to a large value``    ``int` `ans = Integer.MAX_VALUE;` `    ``// generating all subsets``    ``for` `(``int` `i = ``1``; i < (``1` `<< N); i++) {``        ``ArrayList temp = ``new` `ArrayList();``        ``for` `(``int` `j = ``0``; j < N; j++) {``            ``if` `((i & (``1` `<< j)) != ``0``) {``                ``temp.add(A[j]);``            ``}``        ``}``        ``int` `flag = ``0``;` `        ``// checking the first condition``        ``for` `(``int` `j = ``1``; j < temp.size(); j++)``            ``if` `(temp.get(j) < temp.get(j - ``1``))``                ``flag = ``1``;` `        ``// checking the second condition``        ``for` `(``int` `j = ``1``; j < temp.size() - ``1``; j++)``            ``if` `(temp.get(j) - temp.get(j - ``1``)``                ``> temp.get(j + ``1``) - temp.get(j))``                ``flag = ``1``;` `        ``// if both conditions are satisfied consider the``        ``// answer for minimum``        ``if` `(flag == ``0``) {``            ``ans = Math.min(ans, N - (``int``)temp.size());``        ``}``    ``}``    ``return` `ans;``}``// Driver code``public` `static` `void` `main(String args[])``{``    ``// Input``    ``int` `A[] = { ``1``, ``4``, ``5``, ``7``, ``20``, ``21` `};``    ``int` `N = A.length;` `    ``// Function call``    ``System.out.println(minimumDeletions(A, N));``}``}` `// This code is contributed by saurabh_jaiswal.`

## Python3

 `# Python program for the above approach` `# Function for finding minimum deletions so that the array``# becomes non decreasing and the difference between adjacent``# elements also becomes non decreasing``def` `minimumDeletions(A, N):``    ``# initialize answer to a large value``    ``ans ``=` `10``*``*``8` `    ``# generating all subsets``    ``for` `i ``in` `range``(``1``,(``1``< temp[j ``+` `1``] ``-` `temp[j]):``                ``flag ``=` `1` `        ``# if both conditions are satisfied consider the``        ``# answer for minimum``        ``if` `(flag ``=``=` `0``):``            ``ans ``=` `min``(ans, N ``-` `len``(temp))``    ``return` `ans``  ` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``# Input``    ``A``=` `[``1``, ``4``, ``5``, ``7``, ``20``, ``21``]``    ``N ``=` `len``(A)` `    ``# Function call``    ``print` `(minimumDeletions(A, N))` `# This code is contributed by mohit kumar 29.`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{` `// Function for finding minimum deletions so that the array``// becomes non decreasing and the difference between adjacent``// elements also becomes non decreasing``static` `int` `minimumDeletions(``int` `[]A, ``int` `N)``{``    ``// initialize answer to a large value``    ``int` `ans = Int32.MaxValue;` `    ``// generating all subsets``    ``for` `(``int` `i = 1; i < (1 << N); i++) {``        ``List<``int``> temp = ``new` `List<``int``>();``        ``for` `(``int` `j = 0; j < N; j++) {``            ``if` `((i & (1 << j)) != 0) {``                ``temp.Add(A[j]);``            ``}``        ``}``        ``int` `flag = 0;` `        ``// checking the first condition``        ``for` `(``int` `j = 1; j < temp.Count; j++)``            ``if` `(temp[j] < temp[j - 1])``                ``flag = 1;` `        ``// checking the second condition``        ``for` `(``int` `j = 1; j < temp.Count - 1; j++)``            ``if` `(temp[j] - temp[j - 1]``                ``> temp[j + 1] - temp[j])``                ``flag = 1;` `        ``// if both conditions are satisfied consider the``        ``// answer for minimum``        ``if` `(flag == 0) {``            ``ans = Math.Min(ans, N - temp.Count);``        ``}``    ``}``    ``return` `ans;``}` `// Driver code``public` `static` `void` `Main()``{``    ``// Input``    ``int` `[]A = { 1, 4, 5, 7, 20, 21 };``    ``int` `N = A.Length;` `    ``// Function call``    ``Console.Write(minimumDeletions(A, N));``}``}` `// This code is contributed by ipg2016107.`

## Javascript

 ``
Output
`2`

Time Complexity: O(N*2N)
Auxiliary Space: O(N)

Efficient Approach using Dynamic programming: Instead of finding the minimum number of deletions, the problem can be solved by finding the maximum size of the subset, for which the conditions hold. Follow the steps below to solve the problem:

1. Create a 2D array dp, where dp[i][j] stores the minimum number of elements to be deleted from index 1 to i, that satisfy the condition:
1. A[i]-A[i-1]=A[j]
2. Iterate from 0 to N-1 using i, and do the following:
1. Store 1 in dp[i] as the size will be 1.
2. Iterate from i-1 to 0 using j and do the following:
1. Check if A[i] is greater than A[j]. If it is greater, do the following:
1. Store A[i]-A[j] in a variable, say diff.
2. Iterate from 0 to diff using k, and do the following:
1. Store in dp[i] the maximum between dp[i] and dp[j][k]+1.
2. Thus, the transition is:
1. dp[i]=max(dp[i], dp[j][k]+1)
3. Iterate from 0 to MAX using i, and store the maximum value of dp[N-1][i] in a variable, say maxSetSize.
4. The answer would be N-maxSetSize.

Below is the code to implement the approach

## C++

 `#include ``using` `namespace` `std;` `// the maximum value of A[i]``#define MAX 100001` `// Function for finding minimum deletions``// so that the array becomes non-decreasing``// and the difference between adjacent``// elements is also non-decreasing``int` `minimumDeletions(``int` `A[], ``int` `N)``{``    ``// initializing the dp table``    ``// and setting all values to 0``    ``int` `dp[N][MAX];``    ``for` `(``int` `i = 0; i < N; i++)``        ``for` `(``int` `j = 0; j < MAX; j++)``            ``dp[i][j] = 0;` `    ``// Find the maximum size valid set``    ``// that can be taken and then subtract``    ``// its size from N to get``    ``// minimum number of deletions` `    ``for` `(``int` `i = 0; i < N; i++) {``        ``// when selecting only current element``        ``// and deleting all elements``        ``// from 0 to i-1 inclusive``        ``dp[i] = 1;` `        ``for` `(``int` `j = i - 1; j >= 0; j--) {``            ``// if this is true moving from``            ``// index j to i is possible``            ``if` `(A[i] >= A[j]) {``                ``int` `diff = A[i] - A[j];``                ``// iterate over all elements from 0``                ``// to diff and find the max``                ``for` `(``int` `k = 0; k <= diff; k++) {``                    ``dp[i]``                        ``= max(dp[i], dp[j][k] + 1);``                ``}``            ``}``        ``}``    ``}` `    ``// take the max set size``    ``// from dp[N-1] to dp[N-1][MAX]``    ``int` `maxSetSize = -1;``    ``for` `(``int` `i = 0; i < MAX; i++)``        ``maxSetSize = max(maxSetSize, dp[N - 1][i]);` `    ``return` `N - maxSetSize;``}` `// Driver code``int` `main()``{``    ``// Input``    ``int` `A[] = { 1, 4, 5, 7, 20, 21 };``    ``int` `N = ``sizeof``(A) / ``sizeof``(A);` `    ``// Function call``    ``cout << minimumDeletions(A, N) << endl;` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.io.*;` `class` `GFG {` `// the maximum value of A[i]``static` `int` `MAX = ``100001``;` `// Function for finding minimum deletions``// so that the array becomes non-decreasing``// and the difference between adjacent``// elements is also non-decreasing``static` `int` `minimumDeletions(``int` `A[], ``int` `N)``{``    ``// initializing the dp table``    ``// and setting all values to 0``    ``int``[][] dp = ``new` `int``[N][MAX];``    ``for` `(``int` `i = ``0``; i < N; i++)``        ``for` `(``int` `j = ``0``; j < MAX; j++)``            ``dp[i][j] = ``0``;` `    ``// Find the maximum size valid set``    ``// that can be taken and then subtract``    ``// its size from N to get``    ``// minimum number of deletions` `    ``for` `(``int` `i = ``0``; i < N; i++) {``        ``// when selecting only current element``        ``// and deleting all elements``        ``// from 0 to i-1 inclusive``        ``dp[i][``0``] = ``1``;` `        ``for` `(``int` `j = i - ``1``; j >= ``0``; j--) {``            ``// if this is true moving from``            ``// index j to i is possible``            ``if` `(A[i] >= A[j]) {``                ``int` `diff = A[i] - A[j];``                ``// iterate over all elements from 0``                ``// to diff and find the max``                ``for` `(``int` `k = ``0``; k <= diff; k++) {``                    ``dp[i]``                        ``= Math.max(dp[i], dp[j][k] + ``1``);``                ``}``            ``}``        ``}``    ``}` `    ``// take the max set size``    ``// from dp[N-1] to dp[N-1][MAX]``    ``int` `maxSetSize = -``1``;``    ``for` `(``int` `i = ``0``; i < MAX; i++)``        ``maxSetSize = Math.max(maxSetSize, dp[N - ``1``][i]);` `    ``return` `N - maxSetSize;``}`  `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `A[] = { ``1``, ``4``, ``5``, ``7``, ``20``, ``21` `};``    ``int` `N = A.length;` `    ``// Function call``    ``System.out.println(minimumDeletions(A, N));``}``}` `// This code is contributed by code_hunt.`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG{` `// The maximum value of A[i]``static` `int` `MAX = 100001;` `// Function for finding minimum deletions``// so that the array becomes non-decreasing``// and the difference between adjacent``// elements is also non-decreasing``static` `int` `minimumDeletions(``int``[] A, ``int` `N)``{``    ` `    ``// Initializing the dp table``    ``// and setting all values to 0``    ``int``[,] dp = ``new` `int``[N, MAX];``    ``for``(``int` `i = 0; i < N; i++)``        ``for``(``int` `j = 0; j < MAX; j++)``            ``dp[i, j] = 0;` `    ``// Find the maximum size valid set``    ``// that can be taken and then subtract``    ``// its size from N to get``    ``// minimum number of deletions``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ` `        ``// When selecting only current element``        ``// and deleting all elements``        ``// from 0 to i-1 inclusive``        ``dp[i, 0] = 1;` `        ``for``(``int` `j = i - 1; j >= 0; j--)``        ``{``            ` `            ``// If this is true moving from``            ``// index j to i is possible``            ``if` `(A[i] >= A[j])``            ``{``                ``int` `diff = A[i] - A[j];``                ` `                ``// Iterate over all elements from 0``                ``// to diff and find the max``                ``for``(``int` `k = 0; k <= diff; k++)``                ``{``                    ``dp[i, diff] = Math.Max(dp[i, diff],``                                           ``dp[j, k] + 1);``                ``}``            ``}``        ``}``    ``}` `    ``// Take the max set size``    ``// from dp[N-1] to dp[N-1][MAX]``    ``int` `maxSetSize = -1;``    ``for``(``int` `i = 0; i < MAX; i++)``        ``maxSetSize = Math.Max(maxSetSize, dp[N - 1, i]);` `    ``return` `N - maxSetSize;``}` `// Driver Code``public` `static` `void` `Main()``{``    ``int``[] A = { 1, 4, 5, 7, 20, 21 };``    ``int` `N = A.Length;` `    ``// Function call``    ``Console.Write(minimumDeletions(A, N));``}``}` `// This code is contributed by sanjoy_62`

## Javascript

 ``
Output
`2`

Time complexity: O(N2*M), where M is the maximum element in A,
Auxiliary Space: O(N*M)

Efficient Approach using optimized Dynamic programming: In the above approach, the minimum from 0 to diff for each k is calculated repeatedly. To avoid this, a 2D prefix maximum array pref can be maintained where pref[i][j] stores the maximum of the size of subsets such that from 1 to i, the following condition holds:

1. A[i]-A[i-1]=A[j]

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// the maximum value of A[i]``#define MAX 100001` `// Function for finding minimum deletions``// so that the array becomes non-decreasing``// and the difference between adjacent``// elements is also non-decreasing``int` `minimumDeletions(``int` `A[], ``int` `N)``{``    ``// initialize the dp table``    ``// and set all values to 0``    ``// pref[i][j] will contain min(dp[i],``    ``// dp[i], ...dp[i][j])``    ``int` `dp[N][MAX];``    ``int` `pref[N][MAX];``    ``for` `(``int` `i = 0; i < N; i++) {``        ``for` `(``int` `j = 0; j < MAX; j++) {``            ``dp[i][j] = 0;``            ``pref[i][j] = 0;``        ``}``    ``}` `    ``// find the maximum sized valid set``    ``// possible and then subtract its``    ``// size from N to get``    ``// minimum number of deletions``    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// when selecting only the current element and``        ``// deleting all elements from 0 to i-1 inclusive``        ``dp[i] = 1;` `        ``for` `(``int` `j = i - 1; j >= 0; j--) {``            ``// if this is true,``            ``// moving from index j to i is possible``            ``if` `(A[i] >= A[j]) {``                ``int` `diff = A[i] - A[j];``                ``// we can get min(dp[j], .. dp[j])``                ``// from pref array;``                ``dp[i]``                    ``= max(dp[i], pref[j] + 1);``            ``}``        ``}` `        ``// construct the prefix array for this element``        ``pref[i] = dp[i];``        ``for` `(``int` `j = 1; j < MAX; j++)``            ``pref[i][j] = max(dp[i][j], pref[i][j - 1]);``    ``}` `    ``// take the max set size from dp[N-1] to dp[N-1][MAX]``    ``int` `maxSetSize = -1;``    ``for` `(``int` `i = 0; i < MAX; i++)``        ``maxSetSize = max(maxSetSize, dp[N - 1][i]);` `    ``return` `N - maxSetSize;``}` `// Driver code``int` `main()``{``    ``int` `A[] = { 1, 4, 5, 7, 20, 21 };``    ``int` `N = ``sizeof``(A) / ``sizeof``(A);` `    ``// Function call``    ``cout << minimumDeletions(A, N) << endl;` `    ``return` `0;``}`
Output
`2`

Time complexity: O(N*M+N2), where M is the maximum element in A,
Auxiliary Space: O(N*M)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up