[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%。

猜你喜欢

转载自www.cnblogs.com/null-0/p/10662034.html