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;
}
}

浙公网安备 33010602011771号