[Leetcode456] 132模式 峰谷法/单调栈
Posted null-0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Leetcode456] 132模式 峰谷法/单调栈相关的知识,希望对你有一定的参考价值。
题目: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; 5 boolean 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模式 峰谷法/单调栈的主要内容,如果未能解决你的问题,请参考以下文章
leetcodeFace63 股票的最大利润 传统解法到峰谷法的演进过程