845. [陣列][雙指標]陣列中的最長山脈
阿新 • • 發佈:2020-10-25
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; } }