动态规划、贪心在数组中的应用-334. 递增的三元子序列、300. 最长递增子序列

题目链接及描述

334. 递增的三元子序列 - 力扣(LeetCode)

 300. 最长递增子序列 - 力扣(LeetCode)

题目分析

300. 最长递增子序列 - 力扣(LeetCode)

        最长递增子序列作为一道经典的动态规划题目,定义dp[i] 表示下标 i 时数组中存在的最长递增子序列,则可以确定递推公式:

if(nums[i] < nums[i]){

        dp[i] = Math.max(dp[i], dp[j] + 1);

}

        此题之前自己写过很多遍,对于这个思想比较熟悉,就不再赘述了。写这道题目的目的,是和334题的题目进行对比。 此题参考如下:

class Solution {
    public int lengthOfLIS(int[] nums) {
        int ans = Integer.MIN_VALUE;
        int len = nums.length;
        int[] dp = new int[len];
        for(int i = 0; i < len; i++){
            for(int j = 0; j < i; j++){
                if(nums[j] < nums[i]){
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            ans = Math.max(ans, dp[i]);
        }
        return ans + 1;
    }
}

334. 递增的三元子序列 - 力扣(LeetCode)

        对于334题,今天这是第一次写,首先想的一种做法是,采用回溯的思想,遍历构造所有长度对的3的数组,并且在构造的过程中验证是否满足nums[i] < nums[j] < nums[k] 如果不满足直接返回false,如果满足并且得到长度为3时终止循环,并且返回ture。

        感觉使用回溯的做法有些许复杂,随后下班回到出租屋后又打开电脑,联想到【最长递增子序列】上面的那道题。本次无非就是寻找长度为3的最长递增子序列。于是乎使用上面的思路编写代码如下:

class Solution {
    public boolean increasingTriplet(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        for(int i = 0; i < n; i++){
            for(int j = 0; j < i; j++){
                if(nums[j] < nums[i]){
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                    if(dp[i] == 3){
                        return true;
                    }
                }
            }
        }
        return false;
    }
}

        不幸的是,使用这种解法超时了,无法通过所有测试用测,将这个方法写出来就是为了扩展做题思路。

         随后参考答案的写法看到一种贪心的做法,非常巧妙,由于题目是寻找到长度为3的递增数组,所有设置两个阈值first、second。参考图示如下:

        遍历数组nums中的每一个数,如果num在(-oo,first] 之间,说明遇到比当前得到的最小的数更小的数,此时将num 赋值给first,如果num在(first,second] 之间,说明遇到了比当前第二小更小的数,此时将num 赋值给second。如果num 在(second,+oo)之间,说明遇到了第三大的数,此时返回true。终止循环。

        需要将 first 和 second 初始化为Integer.MAX_VALUE。

代码编写

class Solution {
    public boolean increasingTriplet(int[] nums) {
        int first = Integer.MAX_VALUE, second = Integer.MAX_VALUE;
        if(nums.length < 3){
            return false;
        }
        for(int num : nums){
            if(num <= first){
                first = num;
            }else if(num <= second){
                second = num;
            }else{
                return true;
            }
        }
        return false;
    }
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值