1. 程式人生 > >Leetcode---遞增的三元子序列---兩種解法

Leetcode---遞增的三元子序列---兩種解法

遞增的三元子序列

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

數學表示式如下:

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

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

思路

  • 注意i,j,k不一定是連續的,如果是連續的,那麼這道題就非常簡單了
  • 思路一:是利用動態規劃法,將此題轉變為,找到第i個數,該數滿足前i-1個數中至少有兩個數比nums[i]小。
  • 首先額外定義一個數組dp[],初始化全部為0或1,這裡我初始化為1,為1則代表nums[i]之前和包括他本身有多少數<nums[i],當然本身是等於自身的,為0 則代表不包括其本身
  • 在求dp[i]時,遍歷前i-1個數,如果nums[j]<nums[i],那麼dp[i] = max{dp[j]+1,dp[i]}。
  • 如果dp[i]>=3則退出返回True
  • 思路二:這種方式很難想到,定義m1,m2,初始化為最大整數,如果nums[i]<=m1則更新m1,如果nums[i]>m1且nums[i]<m2,則更新m2,此時我們已經得到m1<m2的二元遞增子序列,在後面的過程中,如果有>m2的數,則返回true,當然在迴圈過程中,我們可以一直更新m1,m2的值,如果只更新了m1,我們仍然去尋找滿足之前條件的m1,m2,m3,如果m1,m2 都更新了,那麼更新的值只可能更小,所以新的三元序列也是滿足的。

解法一

if(nums==null||nums.length<3) {
			return false;
		}	
		int[] dp = new int[nums.length];
		dp[0] = 1;
		dp[1]=nums[1]>nums[0]?2:1;
		for(int i=2;i<nums.length;i++) {
			dp[i] = 1;		//初始化賦值為1
			for(int j=0;j<i;j++) {
				if(nums[j]<nums[i]) {
					dp[i] = Math.max(dp[j]+1, dp[i]
); } if(dp[i]>=3) { return true; } } } return false; }

解法二

public boolean increasingTriplet(int[] nums) {

		 int m1 = Integer.MAX_VALUE,m2 = Integer.MAX_VALUE;
		 for(int num:nums) {
		 	if(m1>=num) {
		 		m1 = num;
		 	}else if(m2>=num) {
		 		m2 = num;
		 	}else {
		 		return true;
		 	}
		 }
		 return false;

    }