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

原文地址:https://www.cnblogs.com/null-0/p/10662034.html

时间: 2024-10-09 22:11:08

[Leetcode456] 132模式 峰谷法/单调栈的相关文章

洛谷U4859matrix[单调栈]

题目描述 给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行.每列都是严格递增的. 求给定矩阵中上升子矩阵的数量. 输入输出格式 输入格式: 第一行两个正整数n.m,表示矩阵的行数.列数. 接下来n行,每行m个正整数表示矩阵中的元素. 输出格式: 一个数表示数量. 输入输出样例 输入样例#1: 4 4 1 2 3 4 2 3 4 5 3 4 5 6 4 5 6 7 输出样例#1: 100 出题人的题解是O(n3)感觉可以用单调栈做O(n2),果真可以和仓鼠那道比较像只是需要维护两个tot,一

[Swift]LeetCode456. 132模式 | 32 Pattern

Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that i < j < k and ai < ak < aj. Design an algorithm that takes a list of n numbers as input and checks whether there is a 132 pattern in the list.

洛谷P1823 音乐会的等待 单调栈

洛谷P1823 音乐会的等待 单调栈 维护一个上升的单调栈 用以记录有当前这个数向后能看到几个数 但是每次加入一个数 时 他能看到的 是 单调栈中所有比他小的 和跟他一样的数 比他小的下次就没有用了,所以直接退栈 但是 相同的数到后面还是可能会有贡献的,所以贡献算完以后又要进栈 最后如果栈中还有元素,那么栈顶一定能看到自身,所以+1 1 #include <bits/stdc++.h> 2 #define For(i,j,k) for(int i=j;i<=k;i++) 3 #defin

洛谷P3503 [POI2010]KLO-Blocks 单调栈

洛谷P3503 [POI2010]KLO-Blocks 单调栈首先 因为每个数都要大于k 所以说,我们就可以先将每一个数减去k,然后求他们 的前缀和, 这样问题就转化成了求sum[ r ] - sum[ l ] 运用前缀和 然后 这样的长度 就是 r-l 然后我们考虑怎么求这个最大 首先我们发现 当 i < j 且 sum[ i ] < sum[ j ] 那么 i 一定是 优于 j 的 所以 我们就可以把这些 j 给 忽略 掉了 也就是说 我们 开个单调栈 在 i < j 的情况下 保持

[POI 2008&amp;洛谷P3467]PLA-Postering题解(单调栈)

Description Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长的,从东向西延伸的建筑物链(建筑物的高度不一). Byteburg市的市长Byteasar,决定将这个建筑物链的一侧用海报覆盖住.并且想用最少的海报数量,海报是矩形的. 海报与海报之间不能重叠,但是可以相互挨着(即它们具有公共边),每一个海报都必须贴近墙并且建筑物链的整个一侧必须被覆盖(意思是:海报需要将一侧全部覆盖,并且不能超出建筑物链) 输入格式:第一行为一个整数n

洛谷10月月赛Round.1| P3400 仓鼠窝[单调栈]

题目描述 萌萌哒的Created equal是一只小仓鼠,小仓鼠自然有仓鼠窝啦. 仓鼠窝是一个由n*m个格子组成的行数为n.列数为m的矩阵.小仓鼠现在想要知道,这个矩阵中有多少个子矩阵!(实际上就是有多少个子长方形嘛.)比如说有一个2*3的矩阵,那么1*1的子矩阵有6个,1*2的子矩阵有4个,1*3的子矩阵有2个,2*1的子矩阵有3个,2*2的子矩阵有2个,2*3的子矩阵有1个,所以子矩阵共有6+4+2+3+2+1=18个. 可是仓鼠窝中有的格子被破坏了.现在小仓鼠想要知道,有多少个内部不含被破

bzoj 3039: 玉蟾宫 单调栈或者悬线法求最大子矩阵和

3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖萌...它要找一块矩形土地,要求这片土地都标着'

浅谈单调栈的实现方式和简单应用

一.单调栈的原理和实现方式 1.定义 从栈底元素到栈顶元素呈单调递增或单调递减,栈内序列满足单调性的栈: 2.原理 (1)当新元素在单调性上优于栈顶时(单增栈新元素比栈顶大,单减栈新元素比栈顶小),压栈,栈深+1: (2)当新元素在单调性与栈顶相同(新元素于栈顶相同)或劣于栈顶时(单增栈新元素比栈顶小,单减栈新元素比栈顶大),弹栈,栈深-1: 3.一般实现形式 以单增栈(栈顶为最大值)为例: n为元素数,h为入栈序列,tot为栈深,stack为单增栈: void stacks(){ int st

LeetCode——456.132模式

给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj.设计一个算法,当给定有 n 个数字的序列时,验证这个序列中是否含有132模式的子序列. 注意:n 的值小于15000. 示例1: 输入: [1, 2, 3, 4] 输出: False 解释: 序列中不存在132模式的子序列. 示例 2: 输入: [3, 1, 4, 2] 输出: True 解释: 序列中有 1 个132模式的