Loading

845. [数组][双指针]数组中的最长山脉

845. 数组中的最长山脉

重阳节登高⛰️?

方法一:枚举

上山部分和下山部分分别是严格单调递增严格单调递减的。if (!upSide)不成立时,对应的是”平坡“,左山脚指针将前移。

// 执行耗时:3 ms,击败了69.39% 的Java用户
// 内存消耗:39.5 MB,击败了86.02% 的Java用户

class Solution {
    public int longestMountain(int[] A) {
        if (A == null || A.length < 3) {  // 如果数组长度不足3,直接返回0
            return 0;
        }

        int curLength = 1;
        int maxLength = 0;
        boolean upSide = true;  // 标识位,true表示当前处于上坡,false则表示处于下坡
        for (int i = 1; i < A.length; i++){
            if (A[i] > A[i - 1] && upSide) {
                curLength++;
            } else if (A[i] < A[i - 1] && curLength > 1) {
                upSide = false;
                curLength++;
                maxLength = Math.max(curLength, maxLength);
            } else {
                if (!upSide){
                    i--;  // 判断下一个山脉时,指针前移,而后的当前指针才为第一个需要判断的元素
                }
                upSide = true;
                curLength = 1;
            }
        }
        return maxLength;
    }
}

方法二:双指针

同向双指针的做法类似于直接枚举模拟,要额外注意防止越界。

// 执行耗时:2 ms,击败了99.84% 的Java用户
// 内存消耗:39.4 MB,击败了90.44% 的Java用户

class Solution {
    public int longestMountain(int[] A) {
        if (A == null || A.length < 3) {
            return 0;
        }
        int maxLength = 0;
        int l1 = 0, l2 = 0;
        while (l2 < A.length) {
            while (l2 + 1 < A.length && A[l2 + 1] > A[l2]) {  // 防止越界,判断是否在上山
                l2++;
            }
            int tmp = l2;  // 用于之后判断是否经历下山
            while (l2 > l1 && l2 + 1 < A.length && A[l2+1] < A[l2]) {  // 防止越界,判断是否在下山
                l2++;
            }
            if (l2 == tmp){  // l2没有下山(例如已经到了A的末尾或是处于平坡)
                l2++;        // 此时不符合要求,指针后移
                l1 = l2;
            } else {  // 保存一次山脉长度,更新左指针
                maxLength = Math.max(maxLength, l2 - l1 + 1);
                l1 = l2;
            }
        }
        return maxLength;
    }
}
posted @ 2020-10-25 12:14  上海井盖王  阅读(90)  评论(0)    收藏  举报