Related Articles
Minimum removals required to convert given array to a Mountain Array
• Last Updated : 15 Jan, 2021

Given an array arr[] consisting of N integers​​​, the task is to find the minimum number of array elements required to be removed to to make the given array a mountain array.

A mountain array has the following properties:

• Length of the array ≥ 3.
• There exists some index i (0-based indexing) with 0 < i < N – 1 such that:
• arr < arr < … < arr[i – 1] < arr[i]
• arr[i] > arr[i + 1] > … > arr[arr.length – 1].

Examples:

Input: arr[] = {1, 3, 1}
Output: 0
Explanation: The array itself is a mountain array. Therefore, no removal is required.

Input: arr[] = {2, 1, 1, 5, 6, 2, 3, 1}
Output: 3
Explanation: Removing arr, arr and arr modifies arr[] to {1, 5, 6, 3, 1}, which is a mountain array.

Approach: The idea is to solve this problem using Bottom-Up Dynamic Programming approach. Follow the steps below to solve the problem:

1. If the length of the given array is less than 3, then the array cannot be converted to a mountain array.
2. Otherwise, traverse the array and for every ith element (0 < i < N), find the length of increasing subsequence in the subarrays {arr, …, arr[i – 1]} and store it in an array, say leftIncreasing[].
3. Similarly, find the length of the increasing subsequence in the subarray {arr[i+1], …., arr[N-1]} for every ith element (0 < i < N), and store it in an array, say rightIncreasing[].
4. Find the index i (0 < i < N) which satisfies following conditions:
1. First compulsory condition is the peak condition, which is leftIncreasing[i] > 0 and rightIncreasing[i] > 0.
2. Among all indices, If leftIncreasing[i] + rightIncreasing[i] is maximum, that index is the peak of the mountain array, say X.
5. Return the result as N – (X + 1), adding one to bring array index to length.

Illustration:

Consider the array arr[] = {4, 3, 6, 4, 5}
Therefore, leftIncreasing[] = {0, 0, 1, 1, 2} & rightIncreasing[] = {2, 1, 1, 0, 0}.
There is only one index i = 2 (0-based indexing), for which leftIncreasing > 0 and rightIncreasing > 0.
Therefore, X = leftIncreasing + rightIncreasing = 2.
Therefore, required answer = N – (X + 1) = 5 – (2 + 3)= 2.
One of the possible solution can be {4, 6, 5} i.e. removing 3 (arr) and 4(arr).

Below is the implementation of the above approach:

## C++

 `// C++ program of the above approach``#include ``using` `namespace` `std;`` ` `// Utility function to count array``// elements required to be removed``// to make array a mountain array``int` `minRemovalsUtil(``int` `arr[], ``int` `n)``{``    ``int` `result = 0;``    ``if` `(n < 3) {``        ``return` `-1;``    ``}`` ` `    ``// Stores length of increasing``    ``// subsequence from [0, i-1]``    ``int` `leftIncreasing[n] = {0};`` ` `    ``// Stores length of increasing``    ``// subsequence from [i + 1, n - 1]``    ``int` `rightIncreasing[n] = {0};`` ` `    ``// Iterate for each position up to``    ``// N - 1 to find the length of subsequence``    ``for` `(``int` `i = 1; i < n; i++) ``    ``{``        ``for` `(``int` `j = 0; j < i; j++) ``        ``{`` ` `            ``// If j is less than i, then``            ``// i-th position has leftIncreasing[j]``            ``// + 1 lesser elements including itself``            ``if` `(arr[j] < arr[i]) ``            ``{`` ` `                ``// Check if it is the maximum``                ``// obtained so far``                ``leftIncreasing[i]``                    ``= max(leftIncreasing[i],``                          ``leftIncreasing[j] + 1);``            ``}``        ``}``    ``}`` ` `    ``// Search for increasing subsequence from right``    ``for` `(``int` `i = n - 2; i >= 0; i--)``    ``{``        ``for` `(``int` `j = n - 1; j > i; j--)``        ``{``            ``if` `(arr[j] < arr[i])``            ``{``                ``rightIncreasing[i]``                    ``= max(rightIncreasing[i],``                               ``rightIncreasing[j] + 1);``            ``}``        ``}``    ``}`` ` `    ``// Find the position following the peak``    ``// condition and have maximum leftIncreasing[i]``    ``// + rightIncreasing[i]``    ``for` `(``int` `i = 0; i < n; i++)``    ``{``        ``if` `(leftIncreasing[i] != 0``            ``&& rightIncreasing[i] != 0)``        ``{``            ``result = max(result,``                         ``leftIncreasing[i]``                         ``+ rightIncreasing[i]);``        ``}``    ``}``    ``return` `n - (result + 1);``}`` ` `// Function to count elements to be``// removed to make array a mountain array``void` `minRemovals(``int` `arr[], ``int` `n)``{``    ``int` `ans = minRemovalsUtil(arr, n);`` ` `    ``// Print the answer``    ``cout << ans;``}`` ` `// Driver Code``int` `main()``{`` ` `    ``// Given array``    ``int` `arr[] = { 2, 1, 1, 5, 6, 2, 3, 1 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr); ``       ` `    ``// Function Call``    ``minRemovals(arr, n);``    ``return` `0;``}`` ` `// This code is contributed by Dharanendra L V`

## Java

 `// Java program of the above approach`` ` `import` `java.io.*;``import` `java.util.*;`` ` `class` `GFG {`` ` `    ``// Utility function to count array``    ``// elements required to be removed``    ``// to make array a mountain array``    ``public` `static` `int` `minRemovalsUtil(``        ``int``[] arr)``    ``{``        ``int` `result = ``0``;``        ``if` `(arr.length < ``3``) {``            ``return` `-``1``;``        ``}`` ` `        ``// Stores length of increasing``        ``// subsequence from [0, i-1]``        ``int``[] leftIncreasing``            ``= ``new` `int``[arr.length];`` ` `        ``// Stores length of increasing``        ``// subsequence from [i + 1, n - 1]``        ``int``[] rightIncreasing = ``new` `int``[arr.length];`` ` `        ``// Iterate for each position up to``        ``// N - 1 to find the length of subsequence``        ``for` `(``int` `i = ``1``; i < arr.length; i++) {`` ` `            ``for` `(``int` `j = ``0``; j < i; j++) {`` ` `                ``// If j is less than i, then``                ``// i-th position has leftIncreasing[j]``                ``// + 1 lesser elements including itself``                ``if` `(arr[j] < arr[i]) {`` ` `                    ``// Check if it is the maximum``                    ``// obtained so far``                    ``leftIncreasing[i]``                        ``= Math.max(``                            ``leftIncreasing[i],``                            ``leftIncreasing[j] + ``1``);``                ``}``            ``}``        ``}`` ` `        ``// Search for increasing subsequence from right``        ``for` `(``int` `i = arr.length - ``2``; i >= ``0``; i--) {``            ``for` `(``int` `j = arr.length - ``1``; j > i; j--) {``                ``if` `(arr[j] < arr[i]) {``                    ``rightIncreasing[i]``                        ``= Math.max(rightIncreasing[i],``                                   ``rightIncreasing[j] + ``1``);``                ``}``            ``}``        ``}`` ` `        ``// Find the position following the peak``        ``// condition and have maximum leftIncreasing[i]``        ``// + rightIncreasing[i]``        ``for` `(``int` `i = ``0``; i < arr.length; i++) {``            ``if` `(leftIncreasing[i] != ``0``                ``&& rightIncreasing[i] != ``0``) {``                ``result = Math.max(``                    ``result, leftIncreasing[i]``                                ``+ rightIncreasing[i]);``            ``}``        ``}`` ` `        ``return` `arr.length - (result + ``1``);``    ``}`` ` `    ``// Function to count elements to be``    ``// removed to make array a mountain array``    ``public` `static` `void` `minRemovals(``int``[] arr)``    ``{``        ``int` `ans = minRemovalsUtil(arr);`` ` `        ``// Print the answer``        ``System.out.println(ans);``    ``}`` ` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``// Given array``        ``int``[] arr = { ``2``, ``1``, ``1``, ``5``, ``6``, ``2``, ``3``, ``1` `};`` ` `        ``// Function Call``        ``minRemovals(arr);``    ``}``}`

## Python3

 `# Python3 program of the above approach`` ` `# Utility function to count array``# elements required to be removed``# to make array a mountain array``def` `minRemovalsUtil(arr):``     ` `    ``result ``=` `0``     ` `    ``if` `(``len``(arr) < ``3``):``        ``return` `-``1`` ` `    ``# Stores length of increasing``    ``# subsequence from [0, i-1]``    ``leftIncreasing ``=` `[``0``] ``*` `len``(arr)`` ` `    ``# Stores length of increasing``    ``# subsequence from [i + 1, n - 1]``    ``rightIncreasing ``=` `[``0``] ``*` `len``(arr)`` ` `    ``# Iterate for each position up to``    ``# N - 1 to find the length of subsequence``    ``for` `i ``in` `range``(``1``, ``len``(arr)):``        ``for` `j ``in` `range``(i):`` ` `            ``# If j is less than i, then``            ``# i-th position has leftIncreasing[j]``            ``# + 1 lesser elements including itself``            ``if` `(arr[j] < arr[i]):`` ` `                ``# Check if it is the maximum``                ``# obtained so far``                ``leftIncreasing[i] ``=` `max``(leftIncreasing[i],``                                        ``leftIncreasing[j] ``+` `1``);``                     ` `    ``# Search for increasing subsequence from right``    ``for` `i ``in` `range``(``len``(arr) ``-` `2` `, ``-``1``, ``-``1``):``        ``j ``=` `len``(arr) ``-` `1``         ` `        ``while` `j > i:``            ``if` `(arr[j] < arr[i]) :``                ``rightIncreasing[i] ``=` `max``(rightIncreasing[i],``                                         ``rightIncreasing[j] ``+` `1``)``                                         ` `            ``j ``-``=` `1`` ` `    ``# Find the position following the peak``    ``# condition and have maximum leftIncreasing[i]``    ``# + rightIncreasing[i]``    ``for` `i ``in` `range``(``len``(arr)):``        ``if` `(leftIncreasing[i] !``=` `0` `and` `           ``rightIncreasing[i] !``=` `0``):``            ``result ``=` `max``(result, leftIncreasing[i] ``+``                                ``rightIncreasing[i]);``     ` `    ``return` `len``(arr) ``-` `(result ``+` `1``)`` ` `# Function to count elements to be``# removed to make array a mountain array``def` `minRemovals(arr):``     ` `    ``ans ``=` `minRemovalsUtil(arr)`` ` `    ``# Print the answer``    ``print``(ans)`` ` `# Driver Code``if` `__name__ ``=``=` `"__main__"` `:``         ` `    ``# Given array``    ``arr ``=` `[ ``2``, ``1``, ``1``, ``5``, ``6``, ``2``, ``3``, ``1` `]`` ` `    ``# Function Call``    ``minRemovals(arr)``     ` `# This code is contributed by AnkThon`

## C#

 `// C# program of the above approach``using` `System;`` ` `class` `GFG``{ `` ` `    ``// Utility function to count array``    ``// elements required to be removed  ``    ``// to make array a mountain array``    ``public` `static` `int` `minRemovalsUtil(``int``[] arr)``    ``{``        ``int` `result = 0;``        ``if` `(arr.Length < 3) ``        ``{``            ``return` `-1;``        ``}`` ` `        ``// Stores length of increasing``        ``// subsequence from [0, i-1]``        ``int``[] leftIncreasing``            ``= ``new` `int``[arr.Length];`` ` `        ``// Stores length of increasing``        ``// subsequence from [i + 1, n - 1]``        ``int``[] rightIncreasing = ``new` `int``[arr.Length];`` ` `        ``// Iterate for each position up to``        ``// N - 1 to find the length of subsequence``        ``for` `(``int` `i = 1; i < arr.Length; i++)``        ``{``            ``for` `(``int` `j = 0; j < i; j++)``            ``{`` ` `                ``// If j is less than i, then``                ``// i-th position has leftIncreasing[j]``                ``// + 1 lesser elements including itself``                ``if` `(arr[j] < arr[i]) ``                ``{`` ` `                    ``// Check if it is the maximum``                    ``// obtained so far``                    ``leftIncreasing[i]``                        ``= Math.Max(``                            ``leftIncreasing[i],``                            ``leftIncreasing[j] + 1);``                ``}``            ``}``        ``}`` ` `        ``// Search for increasing subsequence from right``        ``for` `(``int` `i = arr.Length - 2; i >= 0; i--)``        ``{``            ``for` `(``int` `j = arr.Length - 1; j > i; j--) ``            ``{``                ``if` `(arr[j] < arr[i])``                ``{``                    ``rightIncreasing[i]``                        ``= Math.Max(rightIncreasing[i],``                                   ``rightIncreasing[j] + 1);``                ``}``            ``}``        ``}`` ` `        ``// Find the position following the peak``        ``// condition and have maximum leftIncreasing[i]``        ``// + rightIncreasing[i]``        ``for` `(``int` `i = 0; i < arr.Length; i++)``        ``{``            ``if` `(leftIncreasing[i] != 0``                ``&& rightIncreasing[i] != 0) ``            ``{``                ``result = Math.Max(result, leftIncreasing[i]``                                ``+ rightIncreasing[i]);``            ``}``        ``}``        ``return` `arr.Length - (result + 1);``    ``}`` ` `    ``// Function to count elements to be``    ``// removed to make array a mountain array``    ``public` `static` `void` `minRemovals(``int``[] arr)``    ``{``        ``int` `ans = minRemovalsUtil(arr);`` ` `        ``// Print the answer``        ``Console.WriteLine(ans);``    ``}`` ` `    ``// Driver Code``    ``public` `static` `void` `Main(String[] args)  ``    ``{``        ``// Given array``        ``int``[] arr = {2, 1, 1, 5, 6, 2, 3, 1};`` ` `        ``// Function Call``        ``minRemovals(arr);``    ``}``}``  ` `// This code is contributed by shikhasingrajput.`
Output:
`3`

Time Complexity: O(N2)
Auxiliary Space: O(N)

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.

My Personal Notes arrow_drop_up