Loading

【力扣】845. 数组中的最长山脉

 我们把数组 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。

 

示例 1:

输入:[2,1,4,7,3,2,5]
输出:5
解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。
示例 2:

输入:[2,2,2]
输出:0
解释:不含 “山脉”。
 

提示:

0 <= A.length <= 10000
0 <= A[i] <= 10000

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/longest-mountain-in-array
 

 

class Solution {
    public int longestMountain(int[] A) {
        if(A.length < 3){
            return 0; 
        }
        int startIndex = 0; //山脉的开始索引
        int endIndex = 0; //山脉的结束索引
        int centerIndex = 0; //山脉中间节点索引
        boolean isReduce = false;
        int maxLength = 0;
        for(int i = 1 ; i< A.length ; i++){
            //认为是递增
            if(A[i] > A[i-1]){
                if(centerIndex < i-1){
                    //则认为是重新开始一个新的山脉
                    if(isReduce == true){
                        int tempArrayLength = endIndex - startIndex+1;
                        if(tempArrayLength >= 3){
                            maxLength = Math.max(maxLength,tempArrayLength);
                        }
                    }
                    startIndex = i-1;
                    endIndex = i;
                    centerIndex = i;
                    isReduce = false;
                } else {
                    endIndex = i;
                    centerIndex = i;
                }
                
            } else if(A[i] < A[i-1] && centerIndex != startIndex){
                //认为是递减
                endIndex = i;
                isReduce = true;
                if(i == A.length -1){ //说明已经到了最后一个
                    int tempArrayLength = endIndex - startIndex+1;
                    if(tempArrayLength >= 3){
                        maxLength = Math.max(maxLength,tempArrayLength);
                    }
                }
            } else if(A[i] == A[i-1]) {
                //若是相同,则
                //则认为是重新开始一个新的山脉
                    if(isReduce == true){
                        int tempArrayLength = endIndex - startIndex+1;
                        if(tempArrayLength >= 3){
                            maxLength = Math.max(maxLength,tempArrayLength);
                        }
                    }
                startIndex = i;
                endIndex = i;
                centerIndex = i;
                
            }
        }
        return maxLength;
    }

    public 
}

 

 

时间复杂度:O(n)

空间复杂度:O(1)

 

 

了解下另外的方法:

动态规划:

class Solution {

    //使用动态规划的方法计算最长山脉
    //形成一个山脉的关键是:山顶左边单调递增,右边单调递减
    //我们计算出来每个点的单调递增的数量和单调递减的数量,再得到最大值就可以了
    public int longestMountain(int[] A) {
        int n = A.length;
        if (n == 0) {
            return 0;
        }
        //山顶左边都是单调递增的
        //所以当前节点的单调递增的数量只需要跟左边元素相比,如果大于左边节点,则使用左边元素的数量+1,否则就是0
        int[] left = new int[n];
        for (int i = 1; i < n; ++i) {
            left[i] = A[i - 1] < A[i] ? left[i - 1] + 1 : 0;
        }
        //右边也相同
        int[] right = new int[n];
        for (int i = n - 2; i >= 0; --i) {
            right[i] = A[i + 1] < A[i] ? 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;
    }
}

 

 时间复杂度:O(n)

空间复杂度:O(n) 借助了两个数组

 

posted @ 2020-10-25 16:03  冯廷鑫  阅读(207)  评论(0编辑  收藏  举报