Longest Mountain Subarray
Given an array arr[] with N elements, the task is to find out the longest sub-array which has the shape of a mountain.
A mountain sub-array consists of elements that are initially in ascending order until a peak element is reached and beyond the peak element all other elements of the sub-array are in decreasing order.
Examples:
Input: arr = [2, 2, 2]
Output: 0
Explanation:
No sub-array exists that shows the behavior of a mountain sub-array.
Input: arr = [1, 3, 1, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5]
Output: 11
Explanation:
There are two sub-arrays that can be considered as mountain sub-arrays. The first one is from index 0 – 2 (3 elements) and next one is from index 2 – 12 (11 elements). As 11 > 2, our answer is 11.
Naive Approach:
Go through every possible sub-array and check whether it is a mountain sub-array or not. This might take a long time to find the solution and the time complexity for the above approach can be estimated as O(N*N) to go through every possible sub-array and O(N) to check whether it is a mountain sub-array or not. Thus, the overall time complexity for the program is O(N3) which is very high.
Efficient Approach:
- If the length of the given array is less than 3, print 0 as it is not possible to have a mountain sub-array in such a case.
- Set the maximum length to 0 initially.
- Use the two-pointer technique (‘begin’ pointer and ‘end’ pointer) to find out the longest mountain sub-array in the given array.
- When an increasing sub-array is encountered, mark the beginning index of that increasing sub-array in the ‘begin’ pointer.
- If an index value is found in the ‘end’ pointer then reset the values in both the pointers as it marks the beginning of a new mountain sub-array.
- When a decreasing sub-array us encountered, mark the ending index of the mountain sub-array in the ‘end’ pointer.
- Calculate the length of the current mountain sub-array, compare it with the current maximum length of all-mountain sub-arrays traversed until now and keep updating the current maximum length.
Below is the implementation of the above described efficient approach:
C++
#include <bits/stdc++.h>
using namespace std;
int LongestMountain(vector< int >& a)
{
int i = 0, j = -1,
k = -1, p = 0,
d = 0, n = 0;
if (a.size() < 3) {
return 0;
}
for (i = 0; i < a.size() - 1; i++) {
if (a[i + 1] > a[i]) {
if (k != -1) {
k = -1;
j = -1;
}
if (j == -1) {
j = i;
}
}
else {
if (a[i + 1] < a[i]) {
if (j != -1) {
k = i + 1;
}
if (k != -1 && j != -1) {
if (d < k - j + 1) {
d = k - j + 1;
}
}
}
else {
k = -1;
j = -1;
}
}
}
if (k != -1 && j != -1) {
if (d < k - j + 1) {
d = k - j + 1;
}
}
return d;
}
int main()
{
vector< int > d = { 1, 3, 1, 4,
5, 6, 7, 8,
9, 8, 7, 6, 5 };
cout << LongestMountain(d)
<< endl;
return 0;
}
|
Java
import java.io.*;
class GFG{
public static int LongestMountain( int a[])
{
int i = 0 , j = - 1 , k = - 1 , d = 0 ;
if (a.length < 3 )
return 0 ;
for (i = 0 ; i < a.length - 1 ; i++)
{
if (a[i + 1 ] > a[i])
{
if (k != - 1 )
{
k = - 1 ;
j = - 1 ;
}
if (j == - 1 )
j = i;
}
else
{
if (a[i + 1 ] < a[i])
{
if (j != - 1 )
k = i + 1 ;
if (k != - 1 && j != - 1 )
{
if (d < k - j + 1 )
d = k - j + 1 ;
}
}
else
{
k = - 1 ;
j = - 1 ;
}
}
}
if (k != - 1 && j != - 1 )
{
if (d < k - j + 1 )
d = k - j + 1 ;
}
return d;
}
public static void main (String[] args)
{
int a[] = { 1 , 3 , 1 , 4 , 5 , 6 , 7 ,
8 , 9 , 8 , 7 , 6 , 5 };
System.out.println(LongestMountain(a));
}
}
|
Python3
def LongestMountain(a):
i = 0
j = - 1
k = - 1
p = 0
d = 0
n = 0
if ( len (a) < 3 ):
return 0
for i in range ( len (a) - 1 ):
if (a[i + 1 ] > a[i]):
if (k ! = - 1 ):
k = - 1
j = - 1
if (j = = - 1 ):
j = i
else :
if (a[i + 1 ] < a[i]):
if (j ! = - 1 ):
k = i + 1
if (k ! = - 1 and j ! = - 1 ):
if (d < k - j + 1 ):
d = k - j + 1
else :
k = - 1
j = - 1
if (k ! = - 1 and j ! = - 1 ):
if (d < k - j + 1 ):
d = k - j + 1
return d
d = [ 1 , 3 , 1 , 4 , 5 , 6 ,
7 , 8 , 9 , 8 , 7 , 6 , 5 ]
print (LongestMountain(d))
|
C#
using System;
class GFG{
public static int longestMountain( int []a)
{
int i = 0, j = -1, k = -1,
p = 0, d = 0;
if (a.Length < 3)
return 0;
for (i = 0; i < a.Length - 1; i++)
{
if (a[i + 1] > a[i])
{
if (k != -1)
{
k = -1;
j = -1;
}
if (j == -1)
j = i;
}
else
{
if (a[i + 1] < a[i])
{
if (j != -1)
k = i + 1;
if (k != -1 && j != -1)
{
if (d < k - j + 1)
d = k - j + 1;
}
}
else
{
k = -1;
j = -1;
}
}
}
if (k != -1 && j != -1)
{
if (d < k - j + 1)
d = k - j + 1;
}
return d;
}
public static void Main(String[] args)
{
int []a = {1, 3, 1, 4, 5, 6, 7,
8, 9, 8, 7, 6, 5};
Console.WriteLine(longestMountain(a));
}
}
|
Javascript
<script>
function LongestMountain(a)
{
let i = 0, j = -1, k = -1,
p = 0, d = 0, n = 0;
if (a.length < 3)
return 0;
for (i = 0; i < a.length - 1; i++)
{
if (a[i + 1] > a[i])
{
if (k != -1)
{
k = -1;
j = -1;
}
if (j == -1)
j = i;
}
else
{
if (a[i + 1] < a[i])
{
if (j != -1)
k = i + 1;
if (k != -1 && j != -1)
{
if (d < k - j + 1)
d = k - j + 1;
}
}
else
{
k = -1;
j = -1;
}
}
}
if (k != -1 && j != -1)
{
if (d < k - j + 1)
d = k - j + 1;
}
return d;
}
let a = [ 1, 3, 1, 4, 5, 6, 7,
8, 9, 8, 7, 6, 5 ];
document.write(LongestMountain(a));
</script>
|
Time Complexity: O(N)
Auxiliary Space Complexity: O(1)
Another Approach: Two pointer technique
In this approach we do the following steps:
- First of all, we check the size of the vector or array.
- If the size of the array is less than 3, it means we do not have any type of mountain, hence return 0.
- After this traverse the array and try to find the peak element by using the following condition:
- arr[i]>arr[i-1] and arr[i]>arr[i+1]
- If it is true then proceed the step 6 else increment the traversing pointer.
- Now we are at the peak element of the array, so we take a count integer(to count the length of the subarray) and a pointer ‘j‘, it go the left side of the array to find the left side of the subarray and ‘i’ goes to the right side to find the right part of the subarray.
- From all of this, we can find the “Longest Mountain Subarray”.
Below is the implementation of the above-described efficient approach:
C++
#include <bits/stdc++.h>
using namespace std;
int LongestMountain(vector< int >& arr)
{
int n = arr.size();
if (n < 3)
return 0;
int ans = 0;
for ( int i = 1; i <= n - 2;) {
if (arr[i] > arr[i - 1] and arr[i] > arr[i + 1]) {
int count = 0;
int j = i;
while (arr[j] > arr[j - 1] and j > 0)
count++, j--;
while (arr[i] > arr[i + 1] and i <= n - 2)
count++, i++;
ans = max(ans, count);
}
else
i++;
}
if (ans > 0)
return ans + 1;
return ans;
}
int main()
{
vector< int > d
= { 1, 3, 1, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5 };
cout << LongestMountain(d) << endl;
return 0;
}
|
Java
import java.util.ArrayList;
public class Main {
public static int LongestMountain(ArrayList<Integer> arr)
{
int n = arr.size();
if (n < 3 )
return 0 ;
int ans = 0 ;
for ( int i = 1 ; i <= n - 2 😉 {
if (arr.get(i) > arr.get(i - 1 )
&& arr.get(i) > arr.get(i + 1 )) {
int count = 0 ;
int j = i;
while (j > 0
&& arr.get(j) > arr.get(j - 1 )) {
count++;
j--;
}
while (i <= n - 2
&& arr.get(i) > arr.get(i + 1 )) {
count++;
i++;
}
ans = Math.max(ans, count);
}
else {
i++;
}
}
if (ans > 0 )
return ans + 1 ;
return ans;
}
public static void main(String[] args)
{
ArrayList<Integer> d = new ArrayList<>();
d.add( 1 );
d.add( 3 );
d.add( 1 );
d.add( 4 );
d.add( 5 );
d.add( 6 );
d.add( 7 );
d.add( 8 );
d.add( 9 );
d.add( 8 );
d.add( 7 );
d.add( 6 );
d.add( 5 );
System.out.println(LongestMountain(d));
}
}
|
Python3
import math
def LongestMountain(arr):
n = len (arr)
if n < 3 :
return 0
ans = 0
i = 1
while i < = n - 2 :
if arr[i] > arr[i - 1 ] and arr[i] > arr[i + 1 ]:
count = 0
j = i
while j > 0 and arr[j] > arr[j - 1 ]:
count + = 1
j - = 1
while i < = n - 2 and arr[i] > arr[i + 1 ]:
count + = 1
i + = 1
ans = max (ans, count)
else :
i + = 1
if ans > 0 :
return ans + 1
return ans
d = [ 1 , 3 , 1 , 4 , 5 , 6 , 7 , 8 , 9 , 8 , 7 , 6 , 5 ]
print (LongestMountain(d))
|
C#
using System;
public class Program {
public static int LongestMountain( int [] arr) {
int n = arr.Length;
if (n < 3) {
return 0;
}
int ans = 0;
int i = 1;
while (i <= n - 2) {
if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) {
int count = 0;
int j = i;
while (j > 0 && arr[j] > arr[j - 1]) {
count += 1;
j -= 1;
}
while (i <= n - 2 && arr[i] > arr[i + 1]) {
count += 1;
i += 1;
}
ans = Math.Max(ans, count);
} else {
i += 1;
}
}
if (ans > 0) {
return ans + 1;
}
return ans;
}
public static void Main() {
int [] d = {1, 3, 1, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5};
Console.WriteLine(LongestMountain(d));
}
}
|
Javascript
function LongestMountain(arr) {
let n = arr.length;
if (n < 3) {
return 0;
}
let ans = 0;
let i = 1;
while (i <= n - 2) {
if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) {
let count = 0;
let j = i;
while (j > 0 && arr[j] > arr[j - 1]) {
count++;
j--;
}
while (i <= n - 2 && arr[i] > arr[i + 1]) {
count++;
i++;
}
ans = Math.max(ans, count);
} else {
i++;
}
}
if (ans > 0) {
return ans + 1;
}
return ans;
}
let output = LongestMountain([1, 3, 1, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5]);
console.log(output);
|
Time Complexity: O(n)
Auxiliary Space: O(1)
Last Updated :
16 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...