1. 程式人生 > >LeetCode 456.132 Pattern

LeetCode 456.132 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.

Note: n will be less than 15,000.

Example 1:

Input:
[1, 2, 3, 4] Output: False Explanation: There is no 132 pattern in the sequence.

Example 2:

Input: [3, 1, 4, 2]

Output: True

Explanation: There is a 132 pattern in the sequence: [1, 4, 2].

Example 3:

Input: [-1, 3, 2, 0]

Output: True

Explanation: There are three 132 patterns in the sequence: [-1, 3, 2], [-1, 3, 0] and [-1, 2, 0].

/**************************************************/

題目的分類是棧,但是我一開始沒搞懂和棧有什麼關係,所以我一開始是用很naive的方法去實現的:

- naive的方法很簡單,就是跑兩次O(n*n)的迴圈,找到每個點對應的最遠的較小點以及最近的較大點。顯然只要任意點最遠較小點 比 最近較大點遠,那麼就符合題目要求的132pattern了。時間複雜度是O(n*n),在LeetCode用時排在後40%。

- 學習了一下前10%的程式碼,原來使用棧可以讓問題變得更簡單:從陣列後面向前遍歷,用棧暫時存下所有沒有遇到比自身值更大的值的點,用另一個臨時變數temp存放當前已經遇到了更大值的點中的最大值。只要遍歷過程中遇到比temp小的值,那麼就說明一定存在一個132pattern。顯然這種方法只需要O(n)時間複雜度,快了很多。

最後放一下我的方法的程式碼:

class Solution {
    public boolean find132pattern(int[] nums) {
        int FarthestLess[] = new int[nums.length];
        int NearestLarger[] = new int[nums.length];
        for(int i = 2;i<nums.length;i++)
        {
        	FarthestLess[i] = -1;
        	NearestLarger[i] = -1;
        	for(int j = 0;j<=i/2;j++)
        	{
        		if(nums[j]<nums[i])
        		{
        			FarthestLess[i] = j;
        			break;
        		}
        	}
        	for(int j = i-1;j>0 && j>FarthestLess[i];j--)
        	{
        		if(nums[j]>nums[i])
        		{
        			NearestLarger[i] = j;
        			break;
        		}
        	}
        }
        for(int i = 2;i<nums.length;i++)
        {
        	if(FarthestLess[i]!= -1 && NearestLarger[i]!=-1 && FarthestLess[i]<NearestLarger[i])
        		return true;
        }
        return false;
    }
}