开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 29 天,点击查看活动详情
LeetCode845:数组中的最长山脉
把符合下列属性的数组 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
解释: 不存在山脉子数组。
提示:
思路分析
由本题意可知:
山峰是先递增然后递减,递减反过来看也是递增,从左到右计算最长递增子数组的个数,从右到左计算最长递增子数组的个数。
枚举山顶的实现,用dp1[i]记录第i个节点左侧上升山脉长度,于是dp[i] = dp[i-1] + 1;同样的逻辑进行倒叙遍历,那么所得就是第i个节点右侧上升山脉的长度。
- 1.经过分析可得,我们可以在遍历一次列表之后即可得出题解
- 2.从左往右遍历,当前数比下一个数小的,我们记为ans+1,不过这里有一个判断条件:如果之前右山峰不为零,即tem!=0,那我们需要重置这个左山峰
- 3.当前数大于下一个数,并且左山峰不为零,那我们就可以使右山峰加一
算法代码
public int longestMountain(int[] A) {
int len = A.length;
int left = 0;
int right = 0;
int max = 0;
for (int i = 0; i < len - 1; i++) {
if (A[i] < A[i + 1]) { //表示左山峰
if (right != 0) { //表示上一次是右山峰
left = 0;
right = 0;
}
left++;
} else if (left != 0 && A[i] > A[i + 1]) { //右山峰
right++;
max = Math.max(max, left + right + 1);
} else if (A[i] == A[i + 1]) {
left = 0;
}
}
return max;
}
结果详情
算法复杂度
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!