代码随想录LeetCode | day52&53 动态规划子序列刷题回顾

目录

题目回顾

动态规划相关章节

动态规划五步法:

1.300.最长递增子序列

思考:dp[i]为什么要假设为以第i为结尾的最长递增子序列长度?

2. 674. 最长连续递增序列

思考:与300.最长递增子序列 的区别在哪?

3. 718. 最长重复子数组

思考:为什么会做错?

4. 1143.最长公共子序列

5.1035.不相交的线

6. 53. 最大子序和  动态规划


前沿:撰写博客的目的是为了再刷时回顾进一步完善,其次才是以教为学,所以如果有些博客写的较简陋,是为了保持进度不得已而为之,还请大家多多见谅。

预:看到题目后的思路和实现的代码。

见:参考答案展示。

感思:对比答案后的思考,与之前做过的题目是否有关联。

行:

(1)对于没做出来的题目,阅读答案后重新做一遍;

(2)下次做题可以尝试改善的方向;

(3)有助于理解的相关的题目

优先级:做题进度>学习&总结>默写回顾>做题数量

题目回顾

 

动态规划相关章节

代码随想录刷LeetCode | day39 动态规划刷题回顾

代码随想录刷LeetCode | day41 动态规划刷题回顾

http://t.csdn.cn/9FPWN

动态规划五步法:

  1. 确定dp数组以及下标的含义
  2. 确定递推公式

  3. dp数组如何初始化

  4. 确定遍历顺序

  5. 举例推导dp数组

1.300.最长递增子序列

题目链接:300.最长递增子序列 

思考:dp[i]为什么要假设为以第i为结尾的最长递增子序列长度?

  1. dp[i]以第i为结尾的最长递增子序列长度
    1. 若不以i为结尾,假设以遍历到i时的最长长度。
      1. 当以i节点>先前节点时,无法获得以该先前节点为结尾的最长长度,则不能直接写出递推公式即dp[i] = dp[j]+1不成立。
      2. 只有以i为结尾,才能便于后面比较获得递推公式。
class Solution {
    public int lengthOfLIS(int[] nums) {
        int len = nums.length;
        int[] dp = new int[len];
        int result = 1;
        for(int i = 0;i < len;i++){
            dp[i] = 1;
        }
        for(int i = 1;i < len;i++){
            for(int j = 0;j < i;j++){
                if(nums[i] > nums[j]){
                    dp[i] = Math.max(dp[j]+1,dp[i]);
                }
            }
            result = Math.max(dp[i],result);
        }
        return result;
    }
}

2. 674. 最长连续递增序列

题目链接:674. 最长连续递增序列 

思考:与300.最长递增子序列 的区别在哪?

  1. 最长递增子序列需要与之前的节点全部比较,因为其不需要连续。
  2. 最长连续递增序列则只需与前一个节点比较,若大于则等于前一节点+1。
class Solution {
    public int findLengthOfLCIS(int[] nums) {
        /*
        连续子序列→dp[i]以i为结束的最长连续子序列长度
        nums[i] < nums[i + 1],dp[i] = dp[i-1]+1;
        nums[i] >= nums[i + 1],dp[i] = 1
        */
        int len = nums.length;
        int[] dp = new int[len];
        dp[0] = 1;
        int result = 1;
        for(int i = 1;i < len;i++){
            if(nums[i] > nums[i-1]){
                dp[i] = dp[i-1]+1;
                result = Math.max(dp[i],result);
            }else{
                dp[i] = 1;
            }
        }
        return result;
    }
}

3. 718. 最长重复子数组

题目链接:718. 最长重复子数组

思考:为什么会做错?

  1. dp[i][j]假设为遍历到 i 和 j 时最长的重复子数组。
    1. 所以即使不相等也会赋值给其左上的最大值。
    2. 但若其下节点相等时,则会导致重复考虑。
  2. 正确的dp[i][j]假设:以[i][j]为结尾时最长的重复子数组。
    1. 每次相等时都是在[i-1][j-1]基础上+1,避免重复判断相加的情况。
class Solution {
    public int findLength(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int len2 = nums2.length;
        int[][] dp = new int[len1+1][len2+1];
        int result = 0;
        for(int i = 1;i <= len1;i++){
            for(int j = 1;j <= len2;j++){
                if(nums1[i-1] == nums2[j-1]){
                    dp[i][j] = dp[i-1][j-1]+1;
                    result = Math.max(result,dp[i][j]);
                }

            }

        }
        return result;
    }
}

4. 1143.最长公共子序列

题目链接:1143.最长公共子序列 

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int len1 = text1.length();
        int len2 = text2.length();
        int[][] dp = new int[len1+1][len2+1];
        //int result = 0;
        for(int i = 1;i <= len1;i++){
            for(int j = 1;j <= len2;j++){
                if(text1.charAt(i-1) == text2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1]+1;
                }else{
                    dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]);
                }
            //result = Math.max(dp[i][j],result);
            }

        }
        return dp[len1][len2];
    }
}

5.1035.不相交的线

题目链接:1035.不相交的线

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int len1 = text1.length();
        int len2 = text2.length();
        int[][] dp = new int[len1+1][len2+1];
        //int result = 0;
        for(int i = 1;i <= len1;i++){
            for(int j = 1;j <= len2;j++){
                if(text1.charAt(i-1) == text2.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1]+1;
                }else{
                    dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]);
                }
            //result = Math.max(dp[i][j],result);
            }

        }
        return dp[len1][len2];
    }
}

6. 53. 最大子序和  动态规划

题目链接:53. 最大子序和 动态规划 

class Solution {
    public int maxSubArray(int[] nums) {
        int len = nums.length;
        //int[] dp = new int[len];
        //dp[0] = nums[0];
        int dp = nums[0];
        int result = dp;
        for(int i = 1;i < len;i++){
            if(dp <= 0){
                dp = nums[i];
            }else{
                dp = dp + nums[i];
            }
            result = Math.max(result,dp);
        }
        return result;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值