zoukankan      html  css  js  c++  java
  • [leetCode]845. 数组中的最长山脉

    csdn:https://blog.csdn.net/renweiyi1487/article/details/109270033
    原题地址:https://leetcode-cn.com/problems/longest-mountain-in-array

    我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”:

    B.length >= 3
    存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]
    (注意:B 可以是 A 的任意子数组,包括整个数组 A。)

    给出一个整数数组 A,返回最长 “山脉” 的长度。

    如果不含有 “山脉” 则返回 0。

    动态规化

     由于从左侧山脚到山顶,与从右侧山脚到山顶是严格单调递增的所以可以使用动态规化。
     另$left[i]$表示$A[i]$左侧可以扩展的数量,$right[i]$表示$A[i]$右侧可以扩展的数量,

    • 如果$A[i] > A[i-1]$ 那么$left[i]=left[i-1]+1$;如果$i=0则left[i]=0$

    • 如果$A[i] > A[i+1]$ 那么$right[i]=right[i+1]+1$;如果$i=n-1则right[i]=0$

    计算出所有的$left[],right[]$后就可以枚举山顶,但是需要注意只有当$left[i] > 0 并且 right[i] >0$时A[i]才是山顶。

    class Solution {
        public int longestMountain(int[] A) {
            int n = A.length;
            if (n == 0) {
                return 0;
            }
            // left[i] 表示A[i]左侧最多能扩展的数目
            int[] left = new int[n];
            for (int i = 1; i < n; i++) {
                left[i] = A[i] > A[i-1] ? left[i-1]+1 : 0;
            }
            // right[i] 表示A[i]右侧最多能扩展的数目
            int[] right = new int[n];
            for (int i = n-2; i >=0; i--) {
                right[i] = A[i] > A[i+1] ? right[i+1] + 1 : 0;
            }
            int ans = 0;
            for (int i = 0; i < n; i++) {
                if (left[i] > 0 && right[i] >0) {
                    ans = Math.max(ans, left[i] + right[i] + 1);
                }
            }
            return ans;
        }
    }
    

    双指针

    定义一个左指针初始值为0指向山脚,每次固定left时需要保证:

    • left + 2 < n 因为山脉的长度至少为三
    • 然后设置right 指针为left+1,如果left在山脚则控制right指针爬山
    • 如果right指针爬到的是山顶则控制right指针下山,然后计算山脉长度,如果right指针爬到的不是山顶则让right指针+1,每寻找一次山脚就要重新固定left
    class Solution {
        public int longestMountain(int[] A) {
            int n = A.length;
            if (n == 0) {
                return 0;
            }
            int left = 0, ans = 0;
            while (left + 2 < n) {
                int right = left + 1;
                if (A[left] < A[left+1]) {
                    while (right + 1 < n && A[right] < A[right+1]) {
                        right++;
                    }
                    if (right + 1 < n && A[right] > A[right+1]) {
                        while (right + 1 < n && A[right] > A[right+1]) {
                            right++;
                        }
                        ans = Math.max(ans, right-left+1);
                    } else {
                        right++;
                    }
                }
                left = right;
            }
            return ans;
        }
    }
    
  • 相关阅读:
    R基础-适合于纯小白
    endnote将参考文献导入word中
    百度学术导入endnote出现choose an import filter解决
    数据梳理、降维--主成分分析、超易懂实例及R语言实现
    R语言输出高质量图片
    方向导数,偏导数,梯度
    开通博客
    存储引擎
    消息队列的两种模型
    消息队列的应用场景
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13872391.html
Copyright © 2011-2022 走看看