代码随想录算法训练营第五十二天| 动态规划

Posted by Zhuoqun on March 6, 2023

300.最长递增子序列

这道题我自己想出来了一些。但是还是看的题解才明白怎么做。

本题的dp是当前数可做成的最大的子序列有多长。

这道题的思路就是外循环遍历每个数,内循环遍历从0到当前的数之间 有没有比当前数小的数,如果有,取这些数里面dp[j]值最大的再加一。然后最终这题的结果取的不是dp[size-1],而是dp数组里最大的数。这一点和之前的题也不太一样,之前的题都是取最后一个值。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> dp(nums.size(),1);
        int result = 0;

        for(int i=1; i<nums.size(); i++){
            for(int j=0; j<i; j++){
                if(nums[i] > nums[j]){
                    dp[i] = max(dp[i],dp[j]+1);
                }
            }
            if(dp[i] > result){
                result = dp[i];
            }
        }

        return result;

    }
};

674. 最长连续递增序列

这道题很简单,一下就做出来了。

class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        int result = 1;
        int cur_size = 1;
        for(int i=1; i<nums.size(); i++){
            if(nums[i] > nums[i-1]){
                cur_size++;
            }
            else{
                cur_size = 1;
            }
            if(result < cur_size){
                result = cur_size;
            }
        }
        return result;
    }
};

718. 最长重复子数组

这道题看了视频也没太理解。直到看了图表才懂。还需要再做几遍。

这道题利用了2d数组,如果当前的两个数相等,那么就检查dp[i-1][j-1]的值,也就是说两个数共同倒退一位时两个数的重复子数值是多少。

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        vector<vector<int>> dp(nums1.size()+1,vector<int>(nums1.size()+1,0));
        int result = 0;

        for(int i=1; i<=nums1.size(); i++){
            for(int j=1;j<=nums2.size();j++){
                if(nums1[i-1] == nums2[j-1]){
                    dp[i][j] = dp[i-1][j-1]+1;
                }
                if(dp[i][j] > result){
                result = dp[i][j];
                }
            }
            
        }

        return result;
    }
};