题目链接:https://leetcode.cn/problems/longest-mountain-in-array/
题目大意:给出一个数组arr[]
,定义【山数组】为【长度大于等于3】【前面部分递增,后面部分递减,存在一个山峰元素】的数组。求arr[]
中的最长的是【山数组】的子列。
思路:递增栈当然可以,不过刚好想到另一个写法,感觉还行,于是就这么做了。维护两个数组left[], right[]
,left[i]
表示从i
开始向左递减(即可以作为山峰的左半段)最远的下标;同理,right[i]
表示从i
开始向右递减(即可以作为山峰的右半段)最远的下标。那么如果一个【山数组】以i
为山峰,其长度就是right[i] - left[i] + 1
。最开始初始化所有left[i] = right[i] = i
,因为如果无法延伸(不递减),那么就是到自己为止。
对于left[]
,从左往右遍历,如果是从左往右递增(即从右往左递减)就将左边的下标“传递”过去。显然left[i] <= i
,它的目的是从i
尽可能往左延伸,下标越左越好。
对于right[]
,从右往左遍历,如果是从右往左递增(即从左往右递减)就将右边的下标“传递”过去。显然right[i] >= i
,它的目的是从i
尽可能往右延伸,下标越右越好。
因为山数组的长度大于等于3,因此遍历山峰只需从下标1
到N-2
就好了。注意山数组需要【左边和右边都至少长度为1】,只有左半边或者右半边的不能构成山数组!遍历,保留最长的长度即可。文章来源:https://www.toymoban.com/news/detail-455025.html
完整代码文章来源地址https://www.toymoban.com/news/detail-455025.html
class Solution {
public:
int longestMountain(vector<int>& arr) {
int N = arr.size();
vector<int> left(N, 0);
vector<int> right(N, 0);
for (int i = 0; i < N; i++)
left[i] = right[i] = i;
for (int i = 0; i < N-1; i++) {
if (arr[i] < arr[i+1])
left[i+1] = left[i];
}
for (int i = N-1; i > 0; i--) {
if (arr[i] < arr[i-1])
right[i-1] = right[i];
}
int ans = 0;
for (int i = 1; i < N-1; i++) {
int lp = i - left[i], rp = right[i] - i;
if (lp && rp) {
int len = lp + rp + 1;
ans = max(ans, len);
}
}
return ans;
}
};
到了这里,关于【递增栈】个人练习-Leetcode-845. Longest Mountain in Array的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!