原题地址(中等)
方法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)
