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