You may recall that an array arr
is a mountain array if and only if:
arr.length >= 3
i
(0-indexed) with 0 < i < arr.length - 1
such that:
arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
Given an integer array arr
, return the length of the longest subarray, which is a mountain. Return 0
if there is no mountain subarray.
Example 1:
Input: arr = [2,1,4,7,3,2,5] Output: 5 Explanation: The largest mountain is [1,4,7,3,2] which has length 5.
Example 2:
Input: arr = [2,2,2] Output: 0 Explanation: There is no mountain.
Constraints:
1 <= arr.length <= 104
0 <= arr[i] <= 104
Follow up:
O(1)
space?The problem asks to find the length of the longest mountain subarray within a given integer array. A mountain array is defined as an array with at least three elements where:
arr[i]
such that 0 < i < arr.length - 1
.arr[0] < arr[1] < ... < arr[i]
.arr[i] > arr[i+1] > ... > arr[arr.length - 1]
.Two solutions are presented: one using dynamic programming and another using a single pass.
This approach uses two arrays, f
and g
, to store the lengths of the increasing and decreasing subarrays ending at each index, respectively.
Algorithm:
f
and g
with all 1s (each element is a subarray of length 1).f
. If arr[i] > arr[i-1]
, it extends the increasing subarray, so f[i] = f[i-1] + 1
.g
. If arr[i] > arr[i+1]
, it extends the decreasing subarray, so g[i] = g[i+1] + 1
.i
, if both f[i] > 1
and g[i] > 1
, it means there's a mountain at index i
. The length of this mountain is f[i] + g[i] - 1
(avoid double-counting the peak). Update the maximum length ans
.ans
.Time Complexity: O(N), where N is the length of the array. We iterate through the array twice.
Space Complexity: O(N) to store f
and g
arrays.
Code (Python):
class Solution:
def longestMountain(self, arr: List[int]) -> int:
n = len(arr)
f = [1] * n
g = [1] * n
for i in range(1, n):
if arr[i] > arr[i - 1]:
f[i] = f[i - 1] + 1
ans = 0
for i in range(n - 2, -1, -1):
if arr[i] > arr[i + 1]:
g[i] = g[i + 1] + 1
if f[i] > 1:
ans = max(ans, f[i] + g[i] - 1)
return ans
Similar code implementations exist for Java, C++, and Go in the original response.
This approach iterates through the array only once. It identifies potential mountain peaks and extends the mountain length from the peak in both directions.
Algorithm:
ans
(maximum mountain length) and l
(current index).l + 2 < n
.arr[l] < arr[l+1]
, we might have an increasing sequence, so we find the end of the increasing sequence (r
).r < n - 1
and arr[r] > arr[r+1]
, we have a decreasing sequence after the increasing one (a mountain). Extend r
to find the end of the decreasing sequence. Update ans
.l = r
).Time Complexity: O(N). We iterate through the array at most once. Space Complexity: O(1). We use only a few constant variables.
Code (Python):
class Solution:
def longestMountain(self, arr: List[int]) -> int:
n = len(arr)
ans = l = 0
while l + 2 < n:
r = l + 1
if arr[l] < arr[r]:
while r + 1 < n and arr[r] < arr[r + 1]:
r += 1
if r < n - 1 and arr[r] > arr[r + 1]:
while r < n - 1 and arr[r] > arr[r + 1]:
r += 1
ans = max(ans, r - l + 1)
else:
r += 1
l = r
return ans
Again, similar code implementations exist for Java, C++, and Go in the original response. Both solutions achieve the same result, but the second one is more efficient in terms of space complexity. Choose the solution that best suits your needs and coding style.