把符合下列属性的数组 arr
称为 山脉数组 :
arr.length >= 3
- 存在下标
i
(0 < i < arr.length - 1
),满足arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
给出一个整数数组 arr
,返回最长山脉子数组的长度。如果不存在山脉子数组,返回 0
。
示例 1:
输入:arr = [2,1,4,7,3,2,5] 输出:5 解释:最长的山脉子数组是 [1,4,7,3,2],长度为 5。
示例 2:
输入:arr = [2,2,2] 输出:0 解释:不存在山脉子数组。
提示:
1 <= arr.length <= 104
0 <= arr[i] <= 104
进阶:
- 你可以仅用一趟扫描解决此问题吗?
- 你可以用
O(1)
空间解决此问题吗?
我们定义两个数组
时间复杂度
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
class Solution {
public int longestMountain(int[] arr) {
int n = arr.length;
int[] f = new int[n];
int[] g = new int[n];
Arrays.fill(f, 1);
Arrays.fill(g, 1);
for (int i = 1; i < n; ++i) {
if (arr[i] > arr[i - 1]) {
f[i] = f[i - 1] + 1;
}
}
int ans = 0;
for (int i = n - 2; i >= 0; --i) {
if (arr[i] > arr[i + 1]) {
g[i] = g[i + 1] + 1;
if (f[i] > 1) {
ans = Math.max(ans, f[i] + g[i] - 1);
}
}
}
return ans;
}
}
class Solution {
public:
int longestMountain(vector<int>& arr) {
int n = arr.size();
int f[n];
int g[n];
fill(f, f + n, 1);
fill(g, g + n, 1);
for (int i = 1; i < n; ++i) {
if (arr[i] > arr[i - 1]) {
f[i] = f[i - 1] + 1;
}
}
int ans = 0;
for (int i = n - 2; ~i; --i) {
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;
}
};
func longestMountain(arr []int) (ans int) {
n := len(arr)
f := make([]int, n)
g := make([]int, n)
for i := range f {
f[i] = 1
g[i] = 1
}
for i := 1; i < n; i++ {
if arr[i] > arr[i-1] {
f[i] = f[i-1] + 1
}
}
for i := n - 2; i >= 0; i-- {
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
}
我们可以枚举山脉的左侧山脚,然后向右寻找山脉的右侧山脚。我们可以使用两个指针
时间复杂度
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
class Solution {
public int longestMountain(int[] arr) {
int n = arr.length;
int ans = 0;
for (int l = 0, r = 0; l + 2 < n; l = r) {
r = l + 1;
if (arr[l] < arr[r]) {
while (r + 1 < n && arr[r] < arr[r + 1]) {
++r;
}
if (r + 1 < n && arr[r] > arr[r + 1]) {
while (r + 1 < n && arr[r] > arr[r + 1]) {
++r;
}
ans = Math.max(ans, r - l + 1);
} else {
++r;
}
}
}
return ans;
}
}
class Solution {
public:
int longestMountain(vector<int>& arr) {
int n = arr.size();
int ans = 0;
for (int l = 0, r = 0; l + 2 < n; l = r) {
r = l + 1;
if (arr[l] < arr[r]) {
while (r + 1 < n && arr[r] < arr[r + 1]) {
++r;
}
if (r + 1 < n && arr[r] > arr[r + 1]) {
while (r + 1 < n && arr[r] > arr[r + 1]) {
++r;
}
ans = max(ans, r - l + 1);
} else {
++r;
}
}
}
return ans;
}
};
func longestMountain(arr []int) (ans int) {
n := len(arr)
for l, r := 0, 0; l+2 < n; l = r {
r = l + 1
if arr[l] < arr[r] {
for r+1 < n && arr[r] < arr[r+1] {
r++
}
if r+1 < n && arr[r] > arr[r+1] {
for r+1 < n && arr[r] > arr[r+1] {
r++
}
ans = max(ans, r-l+1)
} else {
r++
}
}
}
return
}