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(n2)O(n^2)的吧。

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% 的用戶

棧方法

下面是官方給出的棧的實現方法

在這裏插入圖片描述

這個方法的時間複雜度降到了 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;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章