【力扣】845. 数组中的最长山脉
我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”:
B.length >= 3
存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]
(注意:B 可以是 A 的任意子数组,包括整个数组 A。)给出一个整数数组 A,返回最长 “山脉” 的长度。
如果不含有 “山脉” 则返回 0。
示例 1:
输入:[2,1,4,7,3,2,5]
输出:5
解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。
示例 2:输入:[2,2,2]
输出:0
解释:不含 “山脉”。
提示:
0 <= A.length <= 10000
0 <= A[i] <= 10000来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-mountain-in-array
class Solution { public int longestMountain(int[] A) { if(A.length < 3){ return 0; } int startIndex = 0; //山脉的开始索引 int endIndex = 0; //山脉的结束索引 int centerIndex = 0; //山脉中间节点索引 boolean isReduce = false; int maxLength = 0; for(int i = 1 ; i< A.length ; i++){ //认为是递增 if(A[i] > A[i-1]){ if(centerIndex < i-1){ //则认为是重新开始一个新的山脉 if(isReduce == true){ int tempArrayLength = endIndex - startIndex+1; if(tempArrayLength >= 3){ maxLength = Math.max(maxLength,tempArrayLength); } } startIndex = i-1; endIndex = i; centerIndex = i; isReduce = false; } else { endIndex = i; centerIndex = i; } } else if(A[i] < A[i-1] && centerIndex != startIndex){ //认为是递减 endIndex = i; isReduce = true; if(i == A.length -1){ //说明已经到了最后一个 int tempArrayLength = endIndex - startIndex+1; if(tempArrayLength >= 3){ maxLength = Math.max(maxLength,tempArrayLength); } } } else if(A[i] == A[i-1]) { //若是相同,则 //则认为是重新开始一个新的山脉 if(isReduce == true){ int tempArrayLength = endIndex - startIndex+1; if(tempArrayLength >= 3){ maxLength = Math.max(maxLength,tempArrayLength); } } startIndex = i; endIndex = i; centerIndex = i; } } return maxLength; } public }
时间复杂度:O(n)
空间复杂度:O(1)
了解下另外的方法:
动态规划:
class Solution { //使用动态规划的方法计算最长山脉 //形成一个山脉的关键是:山顶左边单调递增,右边单调递减 //我们计算出来每个点的单调递增的数量和单调递减的数量,再得到最大值就可以了 public int longestMountain(int[] A) { int n = A.length; if (n == 0) { return 0; } //山顶左边都是单调递增的 //所以当前节点的单调递增的数量只需要跟左边元素相比,如果大于左边节点,则使用左边元素的数量+1,否则就是0 int[] left = new int[n]; for (int i = 1; i < n; ++i) { left[i] = A[i - 1] < A[i] ? left[i - 1] + 1 : 0; } //右边也相同 int[] right = new int[n]; for (int i = n - 2; i >= 0; --i) { right[i] = A[i + 1] < A[i] ? right[i + 1] + 1 : 0; } //最后求结果 int ans = 0; for (int i = 0; i < n; ++i) { if (left[i] > 0 && right[i] > 0) { ans = Math.max(ans, left[i] + right[i] + 1); } } return ans; } }
时间复杂度:O(n)
空间复杂度:O(n) 借助了两个数组
一个入行不久的Java开发,越学习越感觉知识太多,自身了解太少,只能不断追寻