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(成功,2ms,极快)

3个连续递增子序列
有3个槽位,a,b,c
满足条件 a < b < c,即可
需要将合适的元素填入这3个槽位

比如说:

one=10,two=20,

如果现在n>20,直接成功,

10<n<=20,two=n,

n<10,one=n  (这里是重点),假设n=5,此时one=5,two=20,然后下一步,

如果n<5,与之前一样,设置one=n,

如果20>n>5,设置two=n,此时递增数列是顺序的,one=5,two=15,比之前的10和20都小,而且是two在one后面

如果n>20,成功,因为尽管现在的one在two的后面,但是n比在前面的two大,

而每一个two都有一个比它小的,而且在two前面的one(在这里的一开始的10),(这句话很重要!!!!)

此时10,20,n,成为递增序列

	public boolean increasingTriplet(int[] nums) {
	     int length=nums.length;
	     if(length<=2){
	    	 return false;    	 
	     }
	     int first = nums[0];
	     int second = Integer.MAX_VALUE;
	     for(int i=1;i<length;i++) {
	    	 int now = nums[i];
	    	 if(now <= first) {
	    		 first = now;
	    		 continue;
	    	 }
	    	 if(now <= second) {
	    		 second = now;
	    		 continue;
	    	 }
	    	 return true;
	     }
	     return false;
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值