代码随想录训练营第五十三天

1.最长公共子序列 题1143

①dp数组的含义

二维dp数组,dp[i] [j] 表示以[0,i-1]的text1和以[0,j-1]的text2的最长公共子序列。

②递推公式

要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同

如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i] [j] = dp[i - 1] [j - 1] + 1;

如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。

即:dp[i] [j] = max(dp[i - 1] [j], dp[i] [j - 1])。

if (text1[i - 1] == text2[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}

所以有

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));//注意这里长度要+1
        for (int i = 1; i <= text1.size(); i++) {
            for (int j = 1; j <= text2.size(); j++) {
                if (text1[i - 1] == text2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[text1.size()][text2.size()];  //这里最大值在末尾
    }
};

2.不相交的线 题1035

原理与上题相同

3.最大子序和 题53

①dp数组定义

dp[i]为以nums[i]为结尾的最大子序和。

②递推公式

最大子序和有两种情况,要么是dp[i-1] +nums[i],连续的情况;要么是从nums[i]重新开始,另起炉灶。

那就比较这两种情况的大小。

dp[i] = max(dp[i - 1] + nums[i], nums[i]);

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size() == 0){
            return 0;
        }
        vector<int> dp(nums.size(),0);
        int result = nums[0];  //注意这里取nums[0],因为遍历顺序从左到右,那么后面的子序列应该跟下标为0的子序列取比较。
        dp[0] = nums[0];
        for(int i = 1;i < nums.size();i++){
            dp[i] = max(dp[i-1]+nums[i],nums[i]);
            if(dp[i] >= result){
                result = dp[i];
            }
        }
        return result;
    }
};

你可能感兴趣的:(算法,动态规划,leetcode)