Advertisement
Home Data Structure Arrays Find Maximum Length of a Mountain Subarray

Find Maximum Length of a Mountain Subarray

0
Advertisement

Title: Find Maximum Length of a Mountain Subarray

In this guide, you’ll learn how to find the maximum length of a mountain subarray inside an integer array using Java. A mountain subarray is a contiguous run of elements that strictly increases to a single peak and then strictly decreases, and it must contain at least three elements. We’ll build an efficient two-pointer solution, trace it step by step on a sample input, and cover the common mistakes, edge cases, and interview follow-up questions that come up when this problem appears in a technical interview.

Understanding the Problem

Given an array of integers arr, a subarray arr[left..right] is called a mountain if it satisfies two conditions. First, there is some peak index p with left < p < right such that the values strictly increase from left to p. Second, the values strictly decrease from p to right. Because a mountain needs at least one step up and one step down, its minimum possible length is 3.

The task is to return the length of the longest such subarray anywhere in arr. If no mountain exists at all, for example when the array is flat, strictly increasing, or strictly decreasing from end to end, the answer is 0. The peak itself can never be at index 0 or at the last index, since a peak needs a strictly smaller neighbor on both sides.

Approach to Solve the Problem

The efficient way to solve this is a single forward pass that expands outward from every peak it finds, skipping any index it has already classified. Here’s the step-by-step approach:

  1. If the array has fewer than 3 elements, return 0 immediately since no mountain can fit.
  2. Start a pointer i at index 1, since a peak can never sit at index 0 or at the last index.
  3. At each i, test whether it is a true peak: arr[i-1] < arr[i] and arr[i] > arr[i+1].
  4. If arr[i] is a peak, walk a left pointer backward from i while the array keeps strictly increasing.
  5. Walk a right pointer forward from i while the array keeps strictly decreasing.
  6. Compute the mountain length as right - left + 1 and update maxLength if this mountain is longer than any seen so far.
  7. Move i to right + 1 so the descending slope you just measured is never rescanned as if it were a new ascent.
  8. If arr[i] is not a peak, simply increment i and keep scanning. Repeat until i reaches n - 1, then return maxLength.

Java Program

Here is the complete, compilable Java program implementing the two-pointer approach described above:

Java
public class LongestMountainSubarray {

    public static int longestMountain(int[] arr) {
        int n = arr.length;
        if (n < 3) {
            return 0;
        }

        int maxLength = 0;
        int i = 1;

        while (i < n - 1) {
            boolean isPeak = arr[i - 1] < arr[i] && arr[i] > arr[i + 1];

            if (isPeak) {
                int left = i;
                int right = i;

                while (left > 0 && arr[left - 1] < arr[left]) {
                    left--;
                }

                while (right < n - 1 && arr[right] > arr[right + 1]) {
                    right++;
                }

                int length = right - left + 1;
                maxLength = Math.max(maxLength, length);
                i = right + 1;
            } else {
                i++;
            }
        }

        return maxLength;
    }

    public static void main(String[] args) {
        int[] arr = {2, 1, 4, 7, 3, 2, 5};
        int result = longestMountain(arr);
        System.out.println("Longest mountain length: " + result);
    }
}

Explanation of the Program

  • longestMountain first guards against arrays shorter than 3 elements, since those can never contain a mountain.
  • The outer while (i < n - 1) loop scans every candidate peak position exactly once, never revisiting an index that was already part of a measured mountain.
  • isPeak checks both slopes around arr[i] using strict comparisons, which is what rules out flat plateaus from counting as part of a mountain.
  • When a peak is found, the first inner while loop extends left backward as far as the ascent continues, and the second extends right forward as far as the descent continues.
  • Math.max(maxLength, length) keeps the best mountain seen across the whole array, not just the most recently measured one.
  • Setting i = right + 1 after measuring a mountain is the key optimization. It guarantees every element is visited only a constant number of times, keeping the whole algorithm O(n).

Step-by-Step Trace

Let's trace longestMountain on the input [0, 2, 5, 3, 1, 1, 4], which contains one clear mountain followed by a plateau, so the target output is 5.

iarr[i-1] < arr[i]?arr[i] > arr[i+1]?Is Peak?Mountain LengthmaxLength (after)
1YesNoNo-0
2YesYesYes (left expands to 0, right expands to 4)55
5No-No-5

At the end of each iteration, maxLength holds the length of the longest mountain discovered among all peaks examined so far, and i always points just past the last index already classified, so no element is ever rescanned.

Examples

Example 1: No Mountain Exists

A completely flat array has no strict ascent or descent anywhere, so the answer is 0.

Java
int[] arr1 = {5, 5, 5, 5};
System.out.println(longestMountain(arr1));
// Output: 0 (every pair of neighbors is equal, so no peak qualifies)

Example 2: The Smallest Possible Mountain

A mountain only needs one ascending step and one descending step, so a three-element array can itself be the whole mountain.

Java
int[] arr2 = {1, 3, 2};
System.out.println(longestMountain(arr2));
// Output: 3 (the entire array is itself a mountain)

Example 3: Multiple Mountains, Longest Wins

When an array contains more than one mountain, longestMountain must keep scanning past the first one and report the overall maximum.

Java
int[] arr3 = {2, 1, 4, 7, 3, 2, 5, 6, 8, 4, 1};
System.out.println(longestMountain(arr3));
// Output: 6 (the second mountain, [2, 5, 6, 8, 4, 1], is longer than the first, [1, 4, 7, 3, 2])

Common Mistakes to Avoid

These are the mistakes that most often slip into a first attempt at this problem:

  • Using >= or <= instead of strict > and <. Treating equal neighbors as part of a slope lets flat plateaus count toward a mountain, which inflates the result on inputs like [1, 2, 2, 1]. Always require strictly increasing and strictly decreasing comparisons.
  • Missing boundary guards on the expansion loops. Expanding left below index 0 or right above n - 1 throws ArrayIndexOutOfBoundsException. Guard both inner loops with left > 0 and right < n - 1.
  • Declaring left and right outside the peak check. Reusing stale values from a previous mountain's expansion corrupts the length calculation for the next one. Declare left and right fresh inside the if block, both starting at i.
  • Forgetting to jump i to right + 1. Leaving i where it was and incrementing by one just rescans the descending slope you already measured, which doesn't break correctness but turns the linear algorithm back into a slower one.
  • Returning as soon as the first mountain is found. Some early attempts return the mountain length the moment a peak is detected instead of continuing the scan. Always track a running maxLength and only return it after the loop finishes.

Edge Cases to Test

Before calling this solved, make sure it behaves correctly on these inputs:

  • Array with fewer than 3 elements
  • Strictly increasing array (no descent)
  • Strictly decreasing array (no ascent)
  • All elements equal
  • Plateau between two slopes (equal adjacent values)
  • Multiple mountains of different lengths
  • Peak adjacent to the array boundary
  • Very large array (confirming O(n) performance holds)

Additional Considerations

Time complexity: O(n). Although the expansion loops for left and right look like nested iteration, jumping i to right + 1 guarantees every index is visited only a constant number of times across the entire run, so the total work stays linear in the size of arr.

Space complexity: O(1) extra space. The solution only tracks a handful of index variables, i, left, right, and maxLength, and never allocates an auxiliary array.

Compared to a brute-force approach that checks every possible subarray and verifies its shape, which costs O(n^2) time or worse, the two-pointer scan is the standard efficient solution interviewers expect. It also never mutates the input array, so it's safe to use on read-only data.

Interview Follow-up Questions

An interviewer rarely stops at the base problem. Here are the natural follow-ups, from easiest to hardest:

  • What if you only need to know whether any mountain exists, not its length? Return true the moment the first peak is confirmed on both sides, short-circuiting before scanning the rest of the array.
  • What if the array is read-only and you cannot allocate even a temporary array? The two-pointer approach already satisfies this, since it only uses scalar index variables. Point out that it meets the constraint by design.
  • What if you need the actual start and end indices of the longest mountain, not just its length? Track bestLeft and bestRight alongside maxLength, and update all three together whenever a strictly longer mountain is found.
  • What if duplicate adjacent values should still count toward the slope? Relaxing the comparisons to <= and >= changes the problem definition, since a fully flat array would then register as a trivial mountain, so you would need an extra tie-breaking check to keep plateaus from being misclassified as peaks.
  • What if the array arrives as a stream of unknown length instead of a fixed array? Maintain a small state machine over the last few elements (ascending, descending, or flat) plus the best mountain length seen so far, since you can no longer index backward once elements have scrolled out of view.

Conclusion

Finding the maximum length of a mountain subarray comes down to recognizing that every element belongs to at most one mountain, which is exactly what lets the two-pointer expand-and-skip technique run in a single O(n) pass. Once you're comfortable with longestMountain, try adapting it to return the mountain's indices or to work over a streamed input, both of which are common interview extensions.

You can find more array-based problems like this one, with the same step-by-step trace and interview-style breakdown, in the Arrays category on DailyJavaConcept.