• 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官方题解 - 数组中的最长山脉

  • 相关阅读:
    【ShardingSphere】ShardingSphere-JDBC 快速入门
    【Java】Java8新特性之重复注解与类型注解
    【Java】Java8新特性之时间和日期API
    【Java】Java8新特性之接口默认方法与静态方法
    【数据结构】堆
    【数据结构】二叉树
    JavaFx 创建快捷方式及设置开机启动
    【开源库推荐】#2 AndroidUtilCode Android常用工具类大全(附API使用说明)
    谈谈Android中的消息提示那些坑
    Android CheckBox控件去除图标 样式改造
  • 原文地址:https://www.cnblogs.com/FengZeng666/p/14448513.html
Copyright © 2020-2023  润新知