天天看点

132模式

@author: sdubrz
@date: 2020.0412
题目难度: 中等
考察内容: 栈
原题链接 https://leetcode-cn.com/problems/132-pattern/
题目的著作权归领扣网络所有,商业转载请联系官方授权,非商业转载请注明出处。
解题代码转载请联系 lwyz521604#163.com
           

给定一个整数序列: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模式的子序列: [1, 4, 2].
           

示例 3:

输入: [-1, 3, 2, 0]

输出: True

解释: 序列中有 3 个132模式的的子序列: [-1, 3, 2], [-1, 3, 0] 和 [-1, 2, 0].
           

通过次数

7431

提交次数

28142

常规方法

这道题官方给的标签是栈,但是我没有想出用栈的实现方式。最后写了一个用 ArrayList 实现的版本,提交之后通过了,但是排名比较低。主要的思路就是对于一个数对(a, b),其中 a<b ,判断它们后面的数 c 是否满足 a<c<b 。从左到右扫描一遍数组,用两个 ArrayList 分别存储 a 和 b。时间复杂度应该是 O ( n 2 ) O(n^2) O(n2)的吧。

Java实现如下:

class Solution {
   public boolean find132pattern(int[] nums) {
		if(nums.length<3) {
			return false;
		}
		
		ArrayList<Integer> maxs = new ArrayList<>();
		ArrayList<Integer> mins = new ArrayList<>();
		
		int minIndex0 = 0;
		int maxIndex0 = 0;
		
		int itex = 1;
		while(itex<nums.length && minIndex0>=maxIndex0) {
			if(nums[itex]<nums[minIndex0]) {
				minIndex0 = itex;
				maxIndex0 = itex;
			}else if(nums[itex]>nums[maxIndex0]) {
				maxIndex0 = itex;
			}
			
			itex++;
		}
		
		if(minIndex0>=maxIndex0) {
			return false;
		}
		
		maxs.add(nums[maxIndex0]);
		mins.add(nums[minIndex0]);
		
		while(itex<nums.length) {
			// System.out.println("current number: "+nums[itex]);
			int n = maxs.size();
			for(int i=n-1; i>=0; i--) {
				if(nums[itex]>mins.get(i) && nums[itex]<maxs.get(i)) {
					return true;
				}
			}
			
			if(maxs.size()==mins.size()) { // 一样长
				if(nums[itex]>maxs.get(n-1)) {
					maxs.set(n-1, nums[itex]);
				}else if(nums[itex]<mins.get(n-1)){
					mins.add(nums[itex]);
				}
			}else{  // 最大链表不可能比小链表长
				if(nums[itex]>mins.get(mins.size()-1)) {
					maxs.add(nums[itex]);
				}
			}
			
			itex++;
		}
		
		
		return false;
	}
}
           

在 LeetCode 系统中提交的结果如下

执行结果: 通过 显示详情
执行用时 : 266 ms, 在所有 Java 提交中击败了 22.65% 的用户
内存消耗 : 40.4 MB, 在所有 Java 提交中击败了 35.29% 的用户
           

栈方法

下面是官方给出的栈的实现方法

132模式

这个方法的时间复杂度降到了 O ( n ) O(n) O(n)。官方代码如下

public class Solution {
    public boolean find132pattern(int[] nums) {
        if (nums.length < 3)
            return false;
        Stack < Integer > stack = new Stack < > ();
        int[] min = new int[nums.length];
        min[0] = nums[0];
        for (int i = 1; i < nums.length; i++)
            min[i] = Math.min(min[i - 1], nums[i]);
        for (int j = nums.length - 1; j >= 0; j--) {
            if (nums[j] > min[j]) {
                while (!stack.isEmpty() && stack.peek() <= min[j])
                    stack.pop();
                if (!stack.isEmpty() && stack.peek() < nums[j])
                    return true;
                stack.push(nums[j]);
            }
        }
        return false;
    }
}