Leetcode---遞增的三元子序列---兩種解法
阿新 • • 發佈:2018-12-05
遞增的三元子序列
給定一個未排序的陣列,判斷這個陣列中是否存在長度為 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;
}