Open In App

Longest Mountain Subarray

Improve
Improve
Like Article
Like
Save
Share
Report

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:
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: 

  1. 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.
  2. Set the maximum length to 0 initially.
  3. Use the two-pointer technique (‘begin’ pointer and ‘end’ pointer) to find out the longest mountain sub-array in the given array.
  4. When an increasing sub-array is encountered, mark the beginning index of that increasing sub-array in the ‘begin’ pointer.
  5. 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.
  6. When a decreasing sub-array us encountered, mark the ending index of the mountain sub-array in the ‘end’ pointer.
  7. 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++




// C++ code for Longest Mountain Subarray
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the
// longest mountain subarray
int LongestMountain(vector<int>& a)
{
    int i = 0, j = -1,
        k = -1, p = 0,
        d = 0, n = 0;
 
    // If the size of array is less
    // than 3, the array won't show
    // mountain like behaviour
    if (a.size() < 3) {
        return 0;
    }
 
    for (i = 0; i < a.size() - 1; i++) {
 
        if (a[i + 1] > a[i]) {
 
            // When a new mountain sub-array
            // is found, there is a need to
            // set the variables k, j to -1
            // in order to help calculate the
            // length of new mountain sub-array
            if (k != -1) {
                k = -1;
                j = -1;
            }
 
            // j marks the starting index of a
            // new mountain sub-array. So set the
            // value of j to current index i.
            if (j == -1) {
                j = i;
            }
        }
        else {
 
            // Checks if next element is
            // less than current element
            if (a[i + 1] < a[i]) {
 
                // Checks if starting element exists
                // or not, if the starting element
                // of the mountain sub-array exists
                // then the index of ending element
                // is stored in k
                if (j != -1) {
                    k = i + 1;
                }
 
                // This condition checks if both
                // starting index and ending index
                // exists or not, if yes, the
                // length is calculated.
                if (k != -1 && j != -1) {
 
                    // d holds the length of the
                    // longest mountain sub-array.
                    // If the current length is
                    // greater than the
                    // calculated length, then
                    // value of d is updated.
                    if (d < k - j + 1) {
                        d = k - j + 1;
                    }
                }
            }
 
            // ignore if there is no
            // increase or decrease in
            // the value of the next element
            else {
                k = -1;
                j = -1;
            }
        }
    }
 
    // Checks and calculates
    // the length if last element
    // of the array is the last
    // element of a mountain sub-array
    if (k != -1 && j != -1) {
        if (d < k - j + 1) {
            d = k - j + 1;
        }
    }
    return d;
}
 
// Driver code
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




// Java code for Longest Mountain Subarray
import java.io.*;
 
class GFG{
     
// Function to find the
// longest mountain subarray
public static int LongestMountain(int a[])
{
    int i = 0, j = -1, k = -1, d = 0;
 
    // If the size of array is less than 3,
    // the array won't show mountain like
    // behaviour
    if (a.length < 3)
        return 0;
 
    for(i = 0; i < a.length - 1; i++)
    {
        if (a[i + 1] > a[i])
        {
             
            // When a new mountain sub-array is
            // found, there is a need to set the
            // variables k, j to -1 in order to
            // help calculate the length of new
            // mountain sub-array
            if (k != -1)
            {
                k = -1;
                j = -1;
            }
 
            // j marks the starting index of a
            // new mountain sub-array. So set the
            // value of j to current index i.
            if (j == -1)
                j = i;
        }
        else
        {
             
            // Checks if next element is
            // less than current element
            if (a[i + 1] < a[i])
            {
                 
                // Checks if starting element exists
                // or not, if the starting element of
                // the mountain sub-array exists then
                // the index of ending element is
                // stored in k
                if (j != -1)
                    k = i + 1;
 
                // This condition checks if both
                // starting index and ending index
                // exists or not, if yes,the length
                // is calculated.
                if (k != -1 && j != -1)
                {
 
                    // d holds the length of the
                    // longest mountain sub-array.
                    // If the current length is
                    // greater than the calculated
                    // length, then value of d is
                    // updated.
                    if (d < k - j + 1)
                        d = k - j + 1;
                }
            }
             
            // Ignore if there is no increase
            // or decrease in the value of the
            // next element
            else
            {
                k = -1;
                j = -1;
            }
        }
    }
 
    // Checks and calculates the length
    // if last element of the array is
    // the last element of a mountain sub-array
    if (k != -1 && j != -1)
    {
        if (d < k - j + 1)
            d = k - j + 1;
    }
    return d;
}
 
// Driver code
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));
}
}
 
// This code is contributed by piyush3010


Python3




# Python3 code for longest mountain subarray
 
# Function to find the
# longest mountain subarray
def LongestMountain(a):
     
    i = 0
    j = -1
    k = -1
    p = 0
    d = 0
    n = 0
     
    # If the size of the array is less
    # than 3, the array won't show
    # mountain like behaviour
    if (len(a) < 3):
        return 0
         
    for i in range(len(a) - 1):
        if (a[i + 1] > a[i]):
             
            # When a new mountain sub-array
            # is found, there is a need to
            # set the variables k, j to -1
            # in order to help calculate the
            # length of new mountain sub-array
            if (k != -1):
                k = -1
                j = -1
             
            # j marks the starting index of a
            # new mountain sub-array. So set the
            # value of j to current index i.
            if (j == -1):
                j = i
        else:
             
            # Checks if next element is
            # less than current element
            if (a[i + 1] < a[i]):
                 
                # Checks if starting element exists
                # or not, if the starting element
                # of the mountain sub-array exists
                # then the index of ending element
                # is stored in k
                if (j != -1):
                    k = i + 1
                     
                # This condition checks if both
                # starting index and ending index
                # exists or not, if yes, the
                # length is calculated.
                if (k != -1 and j != -1):
                     
                    # d holds the length of the
                    # longest mountain sub-array.
                    # If the current length is
                    # greater than the
                    # calculated length, then
                    # value of d is updated.
                    if (d < k - j + 1):
                        d = k - j + 1
             
            # Ignore if there is no
            # increase or decrease in
            # the value of the next element
            else:
                k = -1
                j = -1
     
    # Checks and calculates
    # the length if last element
    # of the array is the last
    # element of a mountain sub-array
    if (k != -1 and j != -1):
        if (d < k - j + 1):
            d = k - j + 1
             
    return d
 
# Driver code
d = [ 1, 3, 1, 4, 5, 6,
      7, 8, 9, 8, 7, 6, 5 ]
 
print(LongestMountain(d))
     
# This code is contributed by shubhamsingh10


C#




// C# code for the
// longest Mountain Subarray
using System;
class GFG{
     
// Function to find the
// longest mountain subarray
public static int longestMountain(int []a)
{
  int i = 0, j = -1, k = -1,
  p = 0, d = 0;
 
  // If the size of array is less than 3,
  // the array won't show mountain like
  // behaviour
  if (a.Length < 3)
    return 0;
 
  for(i = 0; i < a.Length - 1; i++)
  {
    if (a[i + 1] > a[i])
    {
      // When a new mountain sub-array is
      // found, there is a need to set the
      // variables k, j to -1 in order to
      // help calculate the length of new
      // mountain sub-array
      if (k != -1)
      {
        k = -1;
        j = -1;
      }
 
      // j marks the starting index of a
      // new mountain sub-array. So set the
      // value of j to current index i.
      if (j == -1)
        j = i;
    }
    else
    {
      // Checks if next element is
      // less than current element
      if (a[i + 1] < a[i])
      {
        // Checks if starting element exists
        // or not, if the starting element of
        // the mountain sub-array exists then
        // the index of ending element is
        // stored in k
        if (j != -1)
          k = i + 1;
 
        // This condition checks if both
        // starting index and ending index
        // exists or not, if yes,the length
        // is calculated.
        if (k != -1 && j != -1)
        {
          // d holds the length of the
          // longest mountain sub-array.
          // If the current length is
          // greater than the calculated
          // length, then value of d is
          // updated.
          if (d < k - j + 1)
            d = k - j + 1;
        }
      }
 
      // Ignore if there is no increase
      // or decrease in the value of the
      // next element
      else
      {
        k = -1;
        j = -1;
      }
    }
  }
 
  // Checks and calculates the length
  // if last element of the array is
  // the last element of a mountain sub-array
  if (k != -1 && j != -1)
  {
    if (d < k - j + 1)
      d = k - j + 1;
  }
  return d;
}
 
// Driver code
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));
}
}
 
// This code is contributed by Princi Singh


Javascript




<script>
 
// Javascript code for Longest Mountain Subarray
 
// Function to find the
// longest mountain subarray
function LongestMountain(a)
{
    let i = 0, j = -1, k = -1,
        p = 0, d = 0, n = 0;
  
    // If the size of array is less than 3,
    // the array won't show mountain like
    // behaviour
    if (a.length < 3)
        return 0;
  
    for(i = 0; i < a.length - 1; i++)
    {
        if (a[i + 1] > a[i])
        {
              
            // When a new mountain sub-array is
            // found, there is a need to set the
            // variables k, j to -1 in order to
            // help calculate the length of new
            // mountain sub-array
            if (k != -1)
            {
                k = -1;
                j = -1;
            }
  
            // j marks the starting index of a
            // new mountain sub-array. So set the
            // value of j to current index i.
            if (j == -1)
                j = i;
        }
        else
        {
              
            // Checks if next element is
            // less than current element
            if (a[i + 1] < a[i])
            {
                  
                // Checks if starting element exists
                // or not, if the starting element of
                // the mountain sub-array exists then
                // the index of ending element is
                // stored in k
                if (j != -1)
                    k = i + 1;
  
                // This condition checks if both
                // starting index and ending index
                // exists or not, if yes,the length
                // is calculated.
                if (k != -1 && j != -1)
                {
  
                    // d holds the length of the
                    // longest mountain sub-array.
                    // If the current length is
                    // greater than the calculated
                    // length, then value of d is
                    // updated.
                    if (d < k - j + 1)
                        d = k - j + 1;
                }
            }
              
            // Ignore if there is no increase
            // or decrease in the value of the
            // next element
            else
            {
                k = -1;
                j = -1;
            }
        }
    }
  
    // Checks and calculates the length
    // if last element of the array is
    // the last element of a mountain sub-array
    if (k != -1 && j != -1)
    {
        if (d < k - j + 1)
            d = k - j + 1;
    }
    return d;
}
 
// Driver Code
     
    let a = [ 1, 3, 1, 4, 5, 6, 7,
                8, 9, 8, 7, 6, 5 ];
                  
    document.write(LongestMountain(a));
            
</script>


Output

11

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

Another Approach: Two pointer technique

In this approach we do the following steps:

  1.  First of all, we check the size of the vector or array.
  2.  If the size of the array is less than 3, it means we do not have any type of mountain, hence return 0.
  3. After this traverse the array and try to find the peak element by using the following condition:
  4.     arr[i]>arr[i-1] and arr[i]>arr[i+1]
  5.  If it is true then proceed the step 6 else increment the traversing pointer.
  6. 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.
  7. From all of this, we can find the “Longest Mountain Subarray”.

 Below is the implementation of the above-described efficient approach:

C++




// C++ code for Longest Mountain Subarray
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the
// longest mountain subarray
int LongestMountain(vector<int>& arr)
{
    int n = arr.size();
    if (n < 3) // base condition for having the mountain
        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;
            // now we find the index where a peak is present
            int j = i; // making a tempeorary element whole
                       // help us to traverse the array
                       // using two pointer techniques
 
            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;
}
 
// Driver code
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 {
    // Function to find the
    // longest mountain subarray
    public static int LongestMountain(ArrayList<Integer> arr)
    {
        int n = arr.size();
        if (n < 3) // base condition for having the mountain
            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;
                // now we find the index where a peak is
                // present
                int j = i; // making a temporary element to
                           // help us traverse the array
                           // using two pointer techniques
 
                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;
    }
 
    // Driver code
    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




# equivalent python code
import math
 
def LongestMountain(arr):
    n = len(arr)
    if n < 3: # base condition for having the mountain
        return 0
    ans = 0
    i = 1
    while i <= n - 2:
        if arr[i] > arr[i - 1] and arr[i] > arr[i + 1]:
            count = 0
            # now we find the index where a peak is present
            j = i # making a temporary element to help us traverse the array using two pointer techniques
            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
 
# Driver code
d = [1, 3, 1, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5]
print(LongestMountain(d))


C#




// C# code for Longest Mountain Subarray
using System;
 
public class Program {
    public static int LongestMountain(int[] arr) {
        int n = arr.Length;
        if (n < 3) { // base condition for having the mountain
            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;
                // now we find the index where a peak is present
                int j = i; // making a temporary element to help us traverse the array using two pointer techniques
                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));
    }
}
 
//This code is contributed by shivamsharma215


Javascript




// define a function LongestMountain that takes one parameter arr
function LongestMountain(arr) {
    // define the length of the array
    let n = arr.length;
 
    // base condition for having the mountain
    if (n < 3) {
        return 0;
    }
 
    // set the ans to 0
    let ans = 0;
 
    // set i to 1
    let i = 1;
 
    // while loop
    while (i <= n - 2) {
        // if statement to check if element at i is greater than element at i-1 and i+1
        if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1]) {
            // set count to 0
            let count = 0;
 
            // now we find the index where a peak is present
            // making a temporary element to help us traverse the array using two pointer techniques
            let j = i;
 
            // while loop to check if j is greater than 0 and element at j is greater than element at j-1
            while (j > 0 && arr[j] > arr[j - 1]) {
                // increment count
                count++;
                // decrement j
                j--;
            }
 
            // while loop to check if i is less than or equal to n - 2 and element at i is greater than element at i+1
            while (i <= n - 2 && arr[i] > arr[i + 1]) {
                // increment count
                count++;
                // increment i
                i++;
            }
 
            // set ans to the maximum value of ans and count
            ans = Math.max(ans, count);
        } else {
            // increment i
            i++;
        }
    }
 
    // if statement to check if ans is greater than 0
    if (ans > 0) {
        // return ans + 1
        return ans + 1;
    }
    // return ans
    return ans;
}
 
// call the function and store the returned value in a variable
let output = LongestMountain([1, 3, 1, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5]);
 
// log the output
console.log(output);


Output

11

Time Complexity: O(n)

Auxiliary Space: O(1)



Last Updated : 16 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads