Loading

LeetCode 845. 数组中的最长山脉

 

思路

方法一:暴力法

对每一个数,都向两边一一扩散,寻找山脉。

 1 class Solution {
 2 public:
 3     int longestMountain(vector<int>& arr) {
 4         int n = arr.size();
 5         
 6         int maxMountainLen = 0;
 7         int left, right;
 8         for(int i = 1; i <= n-2; ++i) {
 9             left = i - 1;
10             right = i + 1;
11             if(arr[left] >= arr[i] || arr[right] >= arr[i]) {
12                 continue;
13             }
14 
15             int tmpLeftValue = arr[left];
16             int tmpRightValue = arr[right];
17             left--;
18             right++;
19             while(left >= 0 && arr[left] < tmpLeftValue) {
20                 tmpLeftValue = arr[left];
21                 --left;
22             }
23 
24             while(right < n && arr[right] < tmpRightValue) {
25                 tmpRightValue = arr[right];
26                 ++right;
27             }
28             
29             if(right-left-1 > maxMountainLen) {
30                 maxMountainLen = right-left-1;
31             }
32         }
33 
34         return maxMountainLen;
35     }
36 };

复杂度分析

时间复杂度:O(n2),比如这种数据:1,2,3,4,5,6,9,7

空间复杂度:O(n)

 

方法二:动态规划 - 枚举山顶

 1 class Solution {
 2 private:
 3     vector<int> left, right;
 4 public:
 5     int longestMountain(vector<int>& arr) {
 6         int n = arr.size();
 7 
 8         left = vector<int>(n, 0);
 9         right = vector<int>(n, 0);
10 
11         for(int i = 1; i < n; ++i) {
12             if(arr[i] > arr[i-1]) {
13                 left[i] = left[i-1] + 1;
14             } else {
15                 left[i] = 0;
16             }
17         }
18 
19         for(int i = n-2; i >= 0; --i) {
20             if(arr[i] > arr[i+1]) {
21                 right[i] = right[i+1] + 1;
22             } else {
23                 right[i] = 0;
24             }
25         }
26 
27         int maxMountainLen = 0;
28         // int lIndex, rIndex;    //答案的左右边界 
29         for(int i = 0; i < n; ++i) {
30             if(left[i] > 0 && right[i] > 0 && left[i]+right[i]+1 > maxMountainLen) {
31                 maxMountainLen = left[i] + right[i] + 1;
32                 // lIndex = i - left[i];
33                 // rIndex = i + right[i];
34             }
35         }
36         
37         //输出"山脉",即答案序列 
38         // for(int i = lIndex; i <= rIndex; ++i) {
39         //     cout << arr[i] << ' ';
40         // }
41 
42         return maxMountainLen;
43     }
44 };

 

方法三:双指针 - 枚举山脚

 1 class Solution {
 2 public:
 3     int longestMountain(vector<int>& arr) {
 4         int n = arr.size();
 5         int ans = 0;
 6         int left = 0;
 7         // int lIndex, rIndex; //答案的左右边界 
 8         while (left + 2 < n) {
 9             int right = left + 1;
10             if (arr[left] < arr[left + 1]) {
11                 while (right + 1 < n && arr[right] < arr[right + 1]) {
12                     ++right;
13                 }
14                 if (right + 1 < n && arr[right] > arr[right + 1]) {
15                     while (right + 1 < n && arr[right] > arr[right + 1]) {
16                         ++right;
17                     }
18                     if(right-left+1 > ans) {
19                         ans = right-left+1;
20                         // lIndex = left;
21                         // rIndex = right;
22                     } 
23                 }
24                 else {
25                     ++right;
26                 }
27             }
28             left = right;
29         }
30         
31         //输出"山脉",即答案序列
32         // for(int i = lIndex; i <= rIndex; ++i) {
33         //     cout << arr[i] << ' ';
34         // }
35         
36         return ans;
37     }
38 };

 

 

参考文章

原文:LeetCode官方题解 - 数组中的最长山脉

posted @ 2021-02-25 18:17  拾月凄辰  阅读(97)  评论(0编辑  收藏  举报