# Minimum removals required to convert given array to a Mountain Array

• Difficulty Level : Expert
• Last Updated : 31 May, 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 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[0] < arr[1] < … < 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[0], arr[1] and arr[5] modifies arr[] to {1, 5, 6, 3, 1}, which is a mountain array.

Approach: The idea is to solve this problem using the 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[0], …, 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 the following conditions:
1. The 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 the maximum, that index is the peak of the mountain array, say X.
5. Return the result as N – (X + 1), adding one to bring the 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[2] > 0 and rightIncreasing[2] > 0.
Therefore, X = leftIncreasing[2] + rightIncreasing[2] = 2.
Therefore, the required answer = N – (X + 1) = 5 – (2 + 3)= 2.
One of the possible solutions could be {4, 6, 5} i.e. removing 3 (arr[1]) and 4(arr[3]).

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[0]);``      ` `    ``// 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.`

## Javascript

 ``
Output:
`3`

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

My Personal Notes arrow_drop_up