LeetCode——334.递增的三元子序列

115 阅读1分钟

递增的三元子序列

1.题目链接:

334. 递增的三元子序列

2.原题描述:

给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。

如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。

3.相关算法

贪心算法:

通过维护两个数,不断更新这两个数,来判断是否存在长度为 3 的递增子序列。

时间复杂度为 O(n),空间复杂度为 O(1)。

动态规划算法:

维护两个数组 dp1 和 dp2,其中 dp1[i] 表示以 nums[i] 为结尾的长度为 1 的递增子序列的最小值,dp2[i] 表示以 nums[i] 为结尾的长度为 2 的递增子序列的最小值。

遍历数组 nums,对于每个数 nums[i],更新 dp1[i] 和 dp2[i],然后判断是否存在长度为 3 的递增子序列。时间复杂度为O(n),空间复杂度为O(n)。

4.本题主要思路

因为是找长度为 3 的递增子序列,所以需要记录两个数:第一个数和第二个数。遍历数组,如果当前数大于第二个数,则必定存在一个递增子序列。

如果当前数小于等于第二个数但大于第一个数,那么可以更新第二个数为当前数。如果当前数小于第一个数,则将第一个数更新为当前数。

最后,如果找到了一个大于第二个数的数,说明存在递增子序列,返回 true,否则返回 false

5.源码分析

贪心算法:

class Solution {
    public boolean increasingTriplet(int[] nums) {
        int first = Integer.MAX_VALUE, second = Integer.MAX_VALUE;	// 1
        for(int i = 0;i<nums.length;++i){							
                if(nums[i]>second){					// 2
                return true;
            }else if(nums[i]>first){					// 3
                second = nums[i];
            }else{							// 4
                first = nums[i];
            }
        } 
        return false;							// 5
    }
}
  1. 创建两个需要维护的前两个比较小的数
  2. for循环遍历,当该数大于第二大的数时则存在三元递增子序列,返回结果true
  3. 该数小于第二大的数,大于第一大的数,则将第二大的数替换成该数
  4. 该数小于第一小的数,则将第一小的数替换成该数
  5. for循环遍历完都没有返回相应的结果,则表明没有符合题目要求的三元子序列,最后返回false

动态规划:

class Solution {
    public boolean increasingTriplet(int[] nums) {
        int n = nums.length;
        if (n < 3) {
            return false;
        }
        int[] dp1 = new int[n];
        int[] dp2 = new int[n];
        Arrays.fill(dp1, Integer.MAX_VALUE);
        Arrays.fill(dp2, Integer.MAX_VALUE);
        dp1[0] = nums[0];
        for (int i = 1; i < n; i++) {
            dp1[i] = Math.min(dp1[i - 1], nums[i]);
        }
        dp2[1] = nums[0];
        for (int i = 2; i < n; i++) {
            dp2[i] = Math.min(dp2[i - 1], nums[i - 1]);
            if (nums[i] > dp2[i]) {
                if (nums[i] > dp1[i - 1]) {
                    return true;
                }
            }
        }
        return false;
    }
}