1. 程式人生 > >leetcode-334- 遞增的三元子序列(increasingly triplet subsequence)-java

leetcode-334- 遞增的三元子序列(increasingly triplet subsequence)-java

題目及測試

package pid334;
/*遞增的三元子序列

給定一個未排序的陣列,判斷這個陣列中是否存在長度為 3 的遞增子序列。

數學表示式如下:

    如果存在這樣的 i, j, k,  且滿足 0 ≤ i < j < k ≤ n-1,
    使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否則返回 false 。

說明: 要求演算法的時間複雜度為 O(n),空間複雜度為 O(1) 。

示例 1:

輸入: [1,2,3,4,5]
輸出: true

示例 2:

輸入: [5,4,3,2,1]
輸出: false





*/


public class main {
	
	public static void main(String[] args) {
		int[][] testTable = {{2,5,3,4,5},{1,1,1,1,1},{5,1,5,5,2,5,4},{1,1,-2,6}};
		for (int[] ito : testTable) {
			test(ito);
		}
	}
		 
	private static void test(int[] ito) {
		Solution solution = new Solution();
		boolean rtn;
		long begin = System.currentTimeMillis();
		System.out.print("ito=");
		for(int num:ito){
			System.out.print(num+" ");
		}
		System.out.println();
		//開始時列印陣列
		
		rtn= solution.increasingTriplet(ito);//執行程式
		long end = System.currentTimeMillis();	
		
		System.out.println("rtn=" );
		System.out.print(rtn);
		System.out.println();
		System.out.println("耗時:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,8ms,超慢)

速度o(n) 空間o(1)
使用兩個陣列,共2個*2,記錄3元陣列的前兩個,總體思路就是找到小的塞到陣列,如果有數比陣列第二個元素大的,則成功

package pid334;

import java.util.Arrays;

public class Solution {
	 public boolean increasingTriplet(int[] nums) {
	     boolean result=false;
	     int length=nums.length;
	     if(length<=2){
	    	 return result;    	 
	     }
		 Integer[] prev=new Integer[2];
		 Integer[] next=new Integer[2];
		 for(int i=0;i<length;i++){
			 int now=nums[i];
			 //next為空
			 if(next[0]==null){
				 //初始化
				 if(prev[0]==null){
					 prev[0]=now;
					 continue;
				 }
				 //到這裡prev【0】一定存在
				 //第二個數沒有且比第一個大
				 if(prev[1]==null&&prev[0]<now){
					 prev[1]=now;
					 continue;
				 }
				//第二個數沒有且比第一個小,則第一個為now
				 if(prev[1]==null&&prev[0]>=now){
					 prev[0]=now;
					 continue;
				 }
				//到這裡prev【1】一定存在
				 //now>prev[1],成功
				 if(now>prev[1]){
					 result=true;
					 break;
				 }
				 //比現在的prev1小,比prev0大,prev1=now,開啟next
				 if(now<prev[1]&&now>prev[0]){
					 prev[1]=now;
					 next[0]=now;
					 continue;
				 }
				 //比現在的prev0小,開啟next
				 if(now<prev[0]){
					 next[0]=now;
					 continue;
				 }
				 
			 }
			 //next0存在
			 else{
				 //前置成功條件
				 if(now>prev[1]){
					 result=true;
					 break;
				 }
				 //next1不存在
				 if(next[1]==null){
					 //now比next0小,則next0為now
					 if(now<=next[0]){
						 next[0]=now;
						 continue;
					 }
					//now比next0大,則next1為now
					 else{
						 next[1]=now;
					 }
				 }
				 //next1存在
				 else{
					//next成功條件
					 if(now>next[1]){
						 result=true;
						 break;
					 }
					 //now比next0小,重置next
					 if(now<next[0]){
						 prev[0]=next[0];
						 prev[1]=next[1];
						 next[0]=now;
						 next[1]=null;
						 continue;
					 }					 
				 }				 
			 }			 
		 }	     
		 return result;
	    }
}

解法2(別人的)

簡化了我這個方法
min1為第一個,min2為第二個
新的數比哪個數小,就重置那個數,否則大就成功了

class Solution {
    public boolean increasingTriplet(int[] nums) {
        if(nums.length<3)
            return false;
        int min1 = Integer.MAX_VALUE;
        int min2 = Integer.MAX_VALUE;
        for(int i=0;i<nums.length;i++)
        {
            //CASE3
            if(nums[i]>min2)
                return true;
            if(nums[i]<min1)
                min1=nums[i];
            if(nums[i]>min1&&nums[i]<min2)
                min2=nums[i];
        }
        return false;
    }
}