LeetCode 845: Longest Mountain in Array – Java Solution with Peak Expansion

Learn how to identify mountain peaks, expand in both directions, and find the longest valid mountain subarray using O(n) time and O(1) extra space.

Krishna Shrivastava
6 views
LinkedInGithubX
0
0
LeetCode 845: Longest Mountain in Array – Java Solution with Peak Expansion
Listen to articleAudio version
Ad

Introduction

A mountain subarray is a contiguous portion of an array that first strictly increases and then strictly decreases.

For example:

[1, 4, 7, 3, 2]
Peak

The array increases toward 7 and decreases after 7, making it a valid mountain of length 5.

The goal is to find the longest mountain subarray in the given array.

This problem is useful for understanding an important array pattern:

Find a valid peak → expand around the peak → calculate the complete structure.

The follow-up also asks for a solution using one pass and O(1) extra space, making it a good interview problem for learning how to optimize array traversal.

Problem Statement

Problem Link -: longest mountain subarray

Given an integer array arr, return the length of the longest contiguous subarray that forms a mountain.

A valid mountain must:

  1. Contain at least 3 elements.
  2. Strictly increase toward a peak.
  3. Strictly decrease after the peak.
  4. Have the peak somewhere between the first and last element.

For example:

[2, 1, 4, 7, 3, 2, 5]

The longest mountain is:

[1, 4, 7, 3, 2]
peak

Therefore:

Answer = 5

Understanding the Pattern

The most important observation is that every valid mountain has a peak.

A peak is an element satisfying:

arr[i - 1] < arr[i] > arr[i + 1]

For example:

1 4 7 3 2
i

At index 2:

4 < 7
7 > 3

Therefore, 7 is a peak.

Once a peak is found, the complete mountain can be discovered by expanding:

peak
1 → 4 → 7 ← 3 ← 2
←──── ────→

The left side continues while values are increasing toward the peak.

The right side continues while values are decreasing away from the peak.

Approach: Expand Around Every Peak

The solution can be divided into three simple steps.

Find every possible peak

Traverse the array from index 1 to n - 2.

For every index:

arr[i - 1] < arr[i] && arr[i] > arr[i + 1]

If this condition is true, i is a valid mountain peak.

Expand toward the left

Starting from the peak, move left while:

arr[left] > arr[left - 1]

This finds how far the increasing portion extends.

Expand toward the right

Starting from the peak, move right while:

arr[right] > arr[right + 1]

This finds how far the decreasing portion extends.

The peak is counted from both sides, so:

mountain length = leftLength + rightLength - 1

Java Solution

The following implementation follows the peak-expansion approach while keeping the extra space at O(1).


class Solution {

// Finds how far the mountain extends toward the left
public int lef(int st, int[] arr) {
int len = 1;

// Keep moving left while the sequence is strictly increasing
// toward the peak.
while (st > 0 && arr[st] > arr[st - 1]) {
len++;
st--;
}

return len;
}

// Finds how far the mountain extends toward the right
public int righ(int st, int[] arr) {
int len = 1;

// Keep moving right while the sequence is strictly decreasing
// after the peak.
while (st < arr.length - 1 && arr[st] > arr[st + 1]) {
len++;
st++;
}

return len;
}

public int longestMountain(int[] arr) {

// A mountain must contain at least 3 elements.
if (arr.length < 3) {
return 0;
}

int ans = 0;

// The first and last elements cannot be peaks,
// so start from index 1 and stop at n - 2.
for (int i = 1; i < arr.length - 1; i++) {

// Check whether arr[i] is a valid peak.
if (arr[i - 1] < arr[i] && arr[i] > arr[i + 1]) {

// Count the increasing part including the peak.
int left = lef(i, arr);

// Count the decreasing part including the peak.
int right = righ(i, arr);

// The peak is counted twice, so subtract 1.
int mountainLength = left + right - 1;

ans = Math.max(ans, mountainLength);
}
}

return ans;
}
}

Dry Run

Consider:

arr = [2, 1, 4, 7, 3, 2, 5]

Start scanning from index 1.

Index 1

2 1 4

1 is not a peak because:

2 < 1 ❌

Move forward.

Index 2

2 1 4 7 3 2 5

For 4:

1 < 4 > 7

Not a peak.

Index 3

2 1 4 7 3 2 5

For 7:

4 < 7 > 3

So 7 is a valid peak.

Expand left

Starting at 7:

1 < 4 < 7

The left side is:

[1, 4, 7]

Length:

3

Expand right

Starting at 7:

7 > 3 > 2

The right side is:

[7, 3, 2]

Length:

3

The peak 7 was counted twice:

3 + 3 - 1 = 5

Therefore:

Longest mountain = 5

Why the Peak Is Counted Twice

This is an important detail in the implementation.

Suppose the mountain is:

1 4 7 3 2
peak

The left traversal counts:

1 4 7

The right traversal counts:

7 3 2

Adding them gives:

3 + 3 = 6

But the 7 belongs to both sections.

Therefore:

6 - 1 = 5

Hence:

left + right - 1

Complexity Analysis

Time Complexity

The overall complexity is:

O(n)

Although the implementation expands left and right whenever a peak is found, each increasing/decreasing section belongs to a particular mountain structure and the total traversal remains linear.

Space Complexity

Only a few integer variables are used:

O(1)

No auxiliary array, HashMap, HashSet, or other data structure is required.

One-Pass Optimization

The same problem can also be solved using a direct one-pass approach.

Instead of explicitly expanding from every peak, maintain:

  1. the length of the current increasing section
  2. the length of the current decreasing section

When an increasing sequence changes into a decreasing sequence, a mountain has been formed.

A compact implementation is:

class Solution {
public int longestMountain(int[] arr) {

int n = arr.length;
int ans = 0;

int up = 0;
int down = 0;

for (int i = 1; i < n; i++) {

// If the sequence starts increasing after a decrease,
// begin tracking a new mountain.
if (arr[i] > arr[i - 1]) {

if (down > 0) {
up = 0;
down = 0;
}

up++;

}
// Continue the decreasing part of the mountain.
else if (arr[i] < arr[i - 1] && up > 0) {

down++;

// A valid mountain requires both an increasing
// and decreasing portion.
ans = Math.max(ans, up + down + 1);

}
// Equal adjacent elements break a mountain completely.
else {

up = 0;
down = 0;
}
}

return ans;
}
}

This approach directly satisfies the follow-up requirement:

Time = O(n)
Space = O(1)

Common Mistakes

Treating a simple increasing sequence as a mountain

1 2 3 4 5

This is not a mountain because there is no decreasing portion.

Treating a simple decreasing sequence as a mountain

5 4 3 2 1

This is also not a mountain because there is no increasing portion.

Allowing equal elements

1 3 3 2

This is not a valid mountain because the increase must be strict.

The conditions require:

<
>

not:

<=
>=

Forgetting the minimum length

A mountain must contain at least three elements:

increasing part + peak + decreasing part

Therefore:

[1, 2] → invalid
[2, 1] → invalid
[1, 2, 1] → valid

Interview Tip

The key to this problem is not the code itself but recognizing the peak structure.

Whenever a problem describes something like:

increasing → peak → decreasing

a useful first thought is:

Can the middle element be treated as a peak and the structure be expanded from there?

This transforms a complicated subarray condition into two simple directional scans.

For interview optimization questions, it is also useful to recognize that the same structure can often be tracked using a few variables instead of repeatedly constructing subarrays.

Conclusion

The Longest Mountain in Array problem demonstrates an important array technique: identifying a structural peak and analyzing the elements around it.

The main ideas are:

  1. A mountain must have a valid peak.
  2. The left side must be strictly increasing.
  3. The right side must be strictly decreasing.
  4. Expanding from each peak provides an intuitive solution.
  5. The problem can also be optimized into a true one-pass O(n), O(1) solution.

The most important pattern to remember is:

Increasing → Peak → Decreasing

Once that pattern becomes familiar, similar problems involving peaks, valleys, increasing/decreasing runs, and subarray structures become significantly easier to recognize.

Ai Assistant Kas