携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,132模式[TreeMap的特点和用法 & 单调栈实践] - 掘金 (juejin.cn)
前言
TreeMap不同于优先队列,TreeMap删除元素O(logn),而且能寻找target值,或者它的floor/ceiling,TreeMap以Key进行排序。对于单调栈的使用很简单,但是要将问题转换到这上面来,还需要多多练习才能信手拈来。
一、132模式
二、枚举1 和 枚举 3
1、枚举3 & 将数组分开 & treemap的寻找速度
// 132模式
public class Find132pattern {
/*
自己的思考记录:
target:寻找132子序列,即寻找波峰,存在返回true
仅仅单减必不可能出现波峰,单增时记住最大值即可,一旦右边找到比起小的就true
先找单增,再单减。
review:
有bug,没这么简单,因为要求第3个不仅要小于第2个,还要大于第一个。
这种题,我的思考度&见识度都不够多。
思路重新分析:枚举三个,纯纯的暴力,2*10^5^,O(n2)都已经超时了,必须往O(nlogn/n)上靠。
本题是一个3元组,如果固定前后,在左侧右侧暴力,肯定超时。
但是固定中间就将数组分为了两组,左边用变量记录最小,右边用TreeMap来做,就可以达到O(logn)
*/
public boolean find132pattern(int[] nums) {
int n = nums.length;
if (n < 3) return false;
TreeMap<Integer, Integer> right = new TreeMap<>();
// 将后边的元素加入map,并分组。
for (int i = nums.length - 1; i > 1; i--) right.put(nums[i], right.getOrDefault(nums[i], 0) + 1);
int min = nums[0];//左侧最小元素。
for (int i = 1; i < nums.length - 1; i++) {
Integer key = right.ceilingKey(min + 1);
if (key != null && key < nums[i]) return true;
right.put(nums[i + 1], right.get(nums[i + 1]) - 1);
if (right.get(nums[i + 1]) == 0) right.remove(nums[i + 1]);
min = Math.min(min, nums[i]);
}
return false;
// review : TreeMap:1-针对key排序;2-可直接firstKey()取最值;3-可ceilingKey/floorKey(int)寻找元素。
// 总结:这种几元组,可往枚举不同的位方向思考。分析几位的大小等关系特性。
}
}
2、枚举1 & 单调栈得到当前3和最到2
// 单调栈解法
class Find132pattern2 {
// 可从后往前枚举1,用单调栈拿到当前的3和最大的2
public boolean find132pattern(int[] nums) {
int n = nums.length;
if(n < 3) return false;
Deque<Integer> que = new LinkedList<>();
que.push(nums[n - 1]);
int second = Integer.MIN_VALUE;// 记录已经得到右边最大的2.
// 从后往前遍历,方便2/3的获取。
for(int i = n - 2;i >= 0;i--){
// 此时2 < 3,要是1 < 2,则1 < 3,满足条件。
if(second > nums[i]) return true;
// 既然nums[i]不能作为1,就把它作为2/3.
while(!que.isEmpty() && nums[i] > que.peek()) second = que.poll();//记录最大的2
// 当nums[i]比已经选出来的值还小就没必要加入进去了,毕竟考虑出栈的都是较大的2.
if(nums[i] > second) que.push(nums[i]);
}
return false;
}
}
总结
1)对于这种三元组问题,应该去固定一些值,找到规律,使用合适的数据结构将时间复杂度降下来。
2)TreeMap:1-针对key排序;2-可直接firstKey()取最值;3-可ceilingKey/floorKey(int)寻找元素。
参考文献
[1] LeetCode 132模式