题目链接
思路:
132模式的数字,只要随意找出一组,即可返回
以3为标准进行判断,这里的1用每个数字及它之前位置的最小值来代替,然后使用栈来判断是否出现了2
首先,使用一个min数组来记录原始数组中每个位置及其之前位置的最小值,也就是找到了1
使用栈,从后向前进行遍历数组,位置记为 i
1)若 min[i] == nums[i],则以这个数字结尾是不能出现132模式的,直接跳过
2)若 min[i] < nums[i],则当前数字可以作为132模式中的3,在此基础上寻找2
(1)栈不空时,则对比栈顶元素与min[i],当栈顶元素小于等于min[i]时,说明以min[i]作为1,nums[i]作为3,栈顶元素作为2的这种模式不存在,需要将栈顶元素弹出,直到栈顶元素大于min[i]或栈空为止
(2)进行完(1)之后,若栈空,说明以当前元素作为3的132模式不存在;若栈不空,并且栈顶元素小于nums[i],则有如下关系:nums[i] > 栈顶元素 > min[i],由于min[i]一定出现在nums[i]之前,栈顶元素一定出现在nums[i]之后,此时找到了132模式,返回true
(3)若第(2)步没有返回,说明当前nums[i]为3的情况下,并未找到132模式,将当前元素压入栈中,作为前面元素的132模式中的2出现,继续遍历寻找
public boolean find132pattern(int[] nums) {
if (nums == null || nums.length < 3) {
return false;
}
Deque<Integer> stack = new ArrayDeque<>();
// 得到位置i及其之前的最小值,记录在min[i]处,作为模式中的1
int[] min = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
if (i != 0) {
min[i] = Math.min(min[i - 1], nums[i]);
} else {
min[i] = nums[i];
}
}
// 从后向前遍历数组
for (int i = nums.length - 1; i >= 0; i--) {
// 如果当前元素比它之前的最小值大,则这个元素可以作为3,min[i]作为1
// 以此为基础,在后面位置寻找2
if (nums[i] > min[i]) {
// 栈顶元素小于当前模式的1,则不可以构成132,弹出
while (!stack.isEmpty() && stack.peek() <= min[i]) {
stack.pop();
}
// 此时若栈不空,且栈顶元素小于nums[i]
// 即:nums[i] > 栈顶元素 > min[i],132模式出现,返回
if (!stack.isEmpty() && stack.peek() < nums[i]) {
return true;
}
// 当前元素作为3未找到132模式,则需要将它压入栈中,它可以作为前面元素的2
stack.push(nums[i]);
}
}
return false;
}