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

版权声明:此文章为许诗宇所写,如需转载,请写下转载文章的地址 https://blog.csdn.net/xushiyu1996818/article/details/83820034

题目及测试

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;
    }
}

猜你喜欢

转载自blog.csdn.net/xushiyu1996818/article/details/83820034