我们把数组 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
class Solution {
public:
int longestMountain(vector<int>& A) {
int left = 0, right = 0;
bool increase = false,decrease = false;
int length = 0;
if (A.size()<=2) return 0;
while(left<A.size()){
if(right<(A.size()-1) && !increase && !decrease && (A[right]<A[right+1])) {
left = right;
increase = true;
}
bool stop = increase && decrease && ((right==A.size()-1) || !(A[right]>A[right+1]));
bool reset = increase && !decrease && ((right==A.size()-1) || !(A[right]<A[right+1]));
bool reverse= increase && !decrease && ((right==A.size()-1) || (A[right]>A[right+1]));
if (reverse){
decrease = true;
}else if (reset){
decrease = false;
increase = false;
left = right;
}else if (stop){
decrease = false;
length = max(length,right-left+1);
left = right;
if(right<(A.size()-1) && (A[right]<A[right+1])) increase = true;
else increase = false;
}
right++;
if(right == A.size()) break;
}
return length;
}
};
题解:采用increase,decrease的方式记录增加,减少的状态。类似于状态机。
后面看到了官方题解里面的一份答案:
不同的是,使用了两层while循环,在进入上山和下山时,都在内部的循环内解决,避免了两种increase,decrease的带来的控制问题,真的是巧妙啊。不过他在下山的每一步时,都会调用max去计算山脉的长度。
int longestMountain(vector<int> &A) {
int res = 0;
int n = A.size();
int i = 1;
while (i < n) {
if (A[ i ] <= A[ i - 1 ]) {
i++;
continue;
}
int start = i;
while (i < n && A[ i ] > A[ i - 1 ]) {
i++;
}
while (i < n && A[ i ] < A[ i - 1 ]) {
i++;
res = max(res, i - start + 1);
}
}
return res;
}