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 };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2020-02-25 Notepad++编写的shell脚本在linux下无法执行的解决方法