[Leetcode456] 132模式 峰谷法/單調棧
阿新 • • 發佈:2019-04-06
一個 lean lock http 匹配 i++ 空間 模式 erl
題目:https://leetcode-cn.com/problems/132-pattern/
思路:
如果某個數左邊比它小的數的最小值,小於它右邊小於它的某個數(不必找最大值),那麽這個序列就符合132模式的定義。如下圖三點所示。
於是有解法1(峰谷法):
1 public static boolean find132pattern(int[] nums) { 2 int min = Integer.MAX_VALUE; 3 int max = Integer.MIN_VALUE; 4 boolean one = false; 5boolean three = false; 6 for (int i = 0; i < nums.length; i++) { 7 // 谷 8 if (!one && i < nums.length - 1 && nums[i + 1] > nums[i]) { 9 one = true; 10 three = false; 11 min = nums[i]; 12 continue; 13 } 14 // 峰 15 if (one && i < nums.length - 1 && nums[i + 1] < nums[i]) { 16 three = true; 17 one = false; 18 max = nums[i]; 19 for (int j = i + 1; j < nums.length; j++) { 20 if (nums[j] < max && nums[j] > min) {21 return true; 22 } 23 } 24 continue; 25 } 26 } 27 return false; 28 }
解法1的基本思路就是先找到一對“1”和“3”,然後掃描“3”的右方,找到“2”。
提交結果是219 ms擊敗39.66、47.3 MB擊敗0%。
解法2(單調棧):
1 public static boolean find132pattern(int[] nums) { 2 if (nums.length == 0) { 3 return false; 4 } 5 // 記錄每一個數左邊的最小值 空間換時間 6 int[] leftMins = new int[nums.length]; 7 // 記錄目前出現的最小值 8 int leftMin = Integer.MAX_VALUE; 9 for (int i = 0; i < nums.length; i++) { 10 leftMins[i] = leftMin; 11 if (nums[i] < leftMin) { 12 leftMin = nums[i]; 13 } 14 } 15 // 從右開始掃描的非遞增棧 存下標 16 Deque<Integer> stack = new LinkedList<>(); 17 for (int i = nums.length - 1; i > 0; i--) { 18 while (!stack.isEmpty() && nums[stack.peekLast()] < nums[i]) { 19 if (nums[stack.pollLast()] > leftMins[i]) { 20 return true; 21 } 22 } 23 stack.offerLast(i); 24 } 25 return false; 26 }
首先從左往右掃描一遍,記錄每個數作為“3”時對應的最小的“1”。然後從右往左掃描,維持一個非遞增棧,把小於或等於棧頂的值壓入棧中,棧中的所有數都是備選的“2”。一旦發現有大於棧頂的數,就以這個數為“3”,用它對應的最小的“1”和棧中備選的“2”比較,一旦有符合“1”<“2”的情況,就匹配成功。
提交結果是19 ms擊敗94.33%,48.3 MB擊敗0%。
[Leetcode456] 132模式 峰谷法/單調棧