day-52 代码随想录算法训练营(19)动态规划 13

300.最长递增子序列

思路:
  • 1.dp存储:以nums[i]为结尾的最长递增子序列的长度为 dp[i]
  • 2.动态转移方程:dp[i]=max(dp[j]+1,dp[i])  
  • 3.初始值都为1  (因为每一个开始都是1)
  • 4.遍历顺序:i:1-n  j:0-i
class Solution {
public:
    int lengthOfLIS(vector& nums) {
        int n=nums.size();
        int res=1;
        vectordp(n,1);
        for(int i=1;inums[j]) //当递增的时候 
                    dp[i]=max(dp[j]+1,dp[i]); 
            }
            if(dp[i]>res) res=dp[i];//更新最长递增子序列
        }
        return res;
    }
};

674.最长连续递增序列

思路一:双指针(连续长度+1,不连续左边界更新为右边界)
class Solution {
public:
    int findLengthOfLCIS(vector& nums) {
        int res=1,left=0,right=0;
        int n=nums.size();
        for(int i=1;inums[i-1]) right++;
            else{
                res=max(res,right-left+1);
                left=right;
            }
        }
        res=max(res,right-left+1);
        return res;
    }
};

思路二:动态规划
  • 1.dp存储:以nums[i]结尾的序列中,最长递增连续子序列为dp[i]
  • 2.动态转移方程 :dp[i]=dp[i-1]+1;
  • 3.初始化:全为1
  • 4.遍历顺序:i:1-n
class Solution {
public:
    int findLengthOfLCIS(vector& nums) {
        int res=1,left=0,right=0;
        int n=nums.size();
        vectordp(n,1);
        for(int i=1;inums[i-1])
                dp[i]=dp[i-1]+1;//只需要考虑连续子数组
            res=max(dp[i],res);
        }
        return res;
    }
};

718.最长重复数组

思路:
  • 1.dp存储:以i-1为结尾的nums1,和以j-1为结尾的nums2,最长重复子数组的长度为dp[i][i]
  • 2.动态转移方程:dp[i][j]=dp[i-1][j-1]+1
  • 3.初始化:全部为0
  • 4.遍历顺序:1-n
class Solution {
public:
    int findLength(vector& nums1, vector& nums2) {
        int n=nums1.size(),m=nums2.size();
        int res=0;
        vector>dp(n+1,vector(m+1,0));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){//nums1中的每一个元素都会对nums2中的每一个元素进行遍历
                //每一个dp[i][j]都存储了重复状态
                if(nums1[i-1]==nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
                if(dp[i][j]>res) res=dp[i][j];
            }  
        }
        return res;
    }
};

你可能感兴趣的:(#,代码随想录算法训练营(19),c++)