[LeetCode] 845. Longest Mountain in Array
Let's call any (contiguous) subarray B (of A)amountainif the following properties hold:
B.length >= 3
- There exists some
0 < i< B.length - 1
such thatB[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]
(Note that B could be any subarray of A, including the entire array A.)
Given an arrayA
of integers,return the length of the longestmountain.
Return0
if there is no mountain.
Example 1:
Input: [2,1,4,7,3,2,5] Output: 5 Explanation: The largest mountain is [1,4,7,3,2] which has length 5.Example 2:
Input: [2,2,2] Output: 0 Explanation: There is no mountain.
Note:
0 <= A.length <= 10000
0 <= A[i] <= 10000
Follow up:
- Can you solve it using only one pass?
- Can you solve it in
O(1)
space?
陣列中的最長山脈。題意是給一個數組,請你返回一個最長的山脈陣列。山脈陣列的定義是
- B.length >= 3
- 存在 0 < i< B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]
這道題不涉及演算法,思路是雙指標。我先給一個需要額外空間的做法。建立兩個額外陣列,與input陣列等長,一個叫做up,一個叫做down,目的是記錄陣列中間單調遞增和單調遞減的部分到底有多長。首先把陣列從右往左掃描,判斷nums[i] > nums[i + 1]。如果滿足這個條件,就down[i] = down[i + 1] + 1,記錄一個區域性的遞減子陣列的長度。一旦不滿足這個條件的話,down[i] = 0。
再次掃描陣列,這一次從左往右掃描,如果nums[i] > nums[i - 1],則up[i] = up[i - 1] + 1,這是在記錄一個區域性的遞增子陣列的長度。同時我們可以計算最大子陣列的長度了,如果up[i] > 0 && down[i] > 0, res = up[i] + down[i] + 1。
時間O(n)
空間O(n)
Java實現
1 class Solution { 2 public int longestMountain(int[] A) { 3 int len = A.length; 4 int res = 0; 5 int[] up = new int[len]; 6 int[] down = new int[len]; 7 for (int i = len - 2; i >= 0; i--) { 8 if (A[i] > A[i + 1]) { 9 down[i] = down[i + 1] + 1; 10 } 11 } 12 13 for (int i = 0; i < len; i++) { 14 if (i > 0 && A[i] > A[i - 1]) { 15 up[i] = up[i - 1] + 1; 16 } 17 if (up[i] > 0 && down[i] > 0) { 18 res = Math.max(res, up[i] + down[i] + 1); 19 } 20 } 21 return res; 22 } 23 }
另外我這裡再提供一種不需要額外空間的做法,只掃描一次。從左往右掃描陣列,如果nums[i] > nums[i - 1],那麼這一段就是上升的,用一個變數記錄最大的上升長度up;這裡我們是用一個while迴圈控制,所以一旦跳出這個while迴圈你就知道可能要開始下降了(也有可能是平的,這裡要注意)。所以這時我們再用一個變數down記錄下降部分的長度,也用while迴圈控制,當不滿足while的條件的時候,down也停止記錄了。此時如果up和down都大於0,就更新res。
時間O(n)
空間O(1)
Java實現
1 class Solution { 2 public int longestMountain(int[] A) { 3 int maxMnt = 0; 4 int i = 1; 5 while (i < A.length) { 6 while (i < A.length && A[i - 1] == A[i]) { 7 i++; 8 } 9 10 int up = 0; 11 while (i < A.length && A[i - 1] < A[i]) { 12 ++up; 13 ++i; 14 } 15 16 int down = 0; 17 while (i < A.length && A[i - 1] > A[i]) { 18 ++down; 19 ++i; 20 } 21 22 if (up > 0 && down > 0) { 23 maxMnt = Math.max(maxMnt, up + down + 1); 24 } 25 } 26 return maxMnt; 27 } 28 }