原题地址(中等)
方法1—动态规划
思路
以i作为山顶,向左右延续
这个是我没想到的,是官方的解法,定义两数组left,right
left[i]表示从i向左可以延续的个数
left[i] = left[i-1] + 1, if A[i] > A[i-1]
= 0, else
right[i]表示从i向右可以延续的个数
right[i] = right[i+1] + 1, if A[i] > A[i+1]
= 0, else
代码
class Solution {
public:
int longestMountain(vector<int>& A) {
int len = A.size();
if(len < 3) return 0;
vector<int> left(len, 0), right(len, 0);
for(int i=1; i<len; i++){
if(A[i] > A[i-1]) left[i] = left[i-1] + 1;
}
for(int i=len-2; i>=0; i--){
if(A[i] > A[i+1]) right[i] = right[i+1] + 1;
}
int ans = 0;
for(int i=1; i<len; i++) {
if(left[i] && right[i])
ans = max(ans, left[i]+right[i]+1);
}
return ans;
}
};
时空复杂度
都是O(N)
方法2—贪心
思路
这个是我自己的思路
思路很简单,就是找从左到右找符合题意的山,找到后,记录山的长度,然后再找,再记录。
有一些细节很坑,提交了两次之后才改对的。
总体来说就是:
找到符合题意的山,记录长度,然后指针直接移动到山的右侧,继续找下一座;
没找到符合题意的山,指针就移动到下一个;
代码
class Solution {
public:
int longestMountain(vector<int>& A) {
int i = 1, len = A.size(), ans = 0;
if(len < 3) return 0;
while(i < len) {
int begin = i-1;
while(i < len && A[i-1] < A[i]){
i++;
}
while(i < len && A[i-1] > A[i]){
i++;
}
int end = i-1;
if(A[(begin+end)/2] > A[begin] && A[(begin+end)/2] > A[end]) ans = max(ans, end-begin+1);
if(begin == end) i++;
}
if(ans < 3) return 0;
else return ans;
}
};
时空复杂度
时间O(N) 空间O(1)