代码随想录算法训练营day50

题目:1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列

参考链接:代码随想录

1143.最长公共子序列

思路:本题要注意**子序列和子数组的区别:子数组必须是连续的,子序列可以不连续,比如abcde的字序列可以为ace。**同样dp五部曲,dp数组,dpij表示text10,i-1和text20,j-1的最长公共子序列长度,这里设置为i-1和j-1同样是方便初始化,和上一题子数组相同;递推公式,当text1i-1和text2j-1相同时,dpij=dpi-1j-1+1,不同时,那么就在text10,i-2和text20,j-1以及text10,i-1和text20,j-2中找最大的,即dpij=max(dpi-1j,dpij-1),注意这里与上一题子数组的区别,上一题对于不等的情况没有任何操作,依旧是初始值0,因为只要不等那么一定构不成连续的子数组;初始化,全部初始化为0,由于我们对dp数组预留了第一行和第一列,不需要特别初始化,在递推公式计算text10和text20时,可以直接根据是否相同往后推出来;遍历顺序,顺序遍历;举例略。本题无需ans,因为遍历的过程中最大值会逐渐往后传递。时间复杂度O(mn)。

cpp 复制代码
class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        vector<vector<int>> dp(text1.size()+1,vector<int>(text2.size()+1,0));//预留位
        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()];
    }
};

1035.不相交的线

思路:本题实际上就是最长公共子序列 ,因为线不相交就相当于序列的顺序不能打乱,方法同上题。dp五部曲:dp数组,dpij表示nums10...i-1和nums20...j-1的最长公共子序列长度;递推公式,当nums1[i-1]==nums2[j-1]时,dp[i][j]=dp[i-1][j-1]+1,不相等时,dp[i][j]=max(dp[i-1][j],dp[i][j-1]);初始化,全部为0;遍历顺序,顺序遍历;举例略。时间复杂度O(mn)。

cpp 复制代码
class Solution {
public:
    int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
        vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,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;
                }
                else{
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        return dp[nums1.size()][nums2.size()];
    }
};

53. 最大子序和

思路:首先回顾一下贪心算法,本题是求最大连续子数组和,可以直接从左往右加,当遇到和为负数的时候,直接结果置0,从下一位开始重新加,因为负数只会拉低结果,这就是贪心的点。然后是dp方法,dp五部曲:dp数组,dpi表示以numsi结尾的最大子序列和;递推公式,本题求的是最大和,所以递推的时候取最大值,推出dpi有两种方式,首先是加上前面的dpi-1+numsi,或者直接重新开始,即numsi其实看dpi-1的正负即可,不过这样有一点贪心的味道在里面;初始化,dp0初始化为nums0;遍历顺序,顺序遍历;举例略。注意返回值不是最终的结果,而是整个dp数组的最大值,我们在遍历过程中记录。时间复杂度O(n)。

cpp 复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        vector<int> dp(nums.size(),0);
        dp[0]=nums[0];
        int ans=dp[0];
        for(int i=1;i<nums.size();i++){
            dp[i]=max(dp[i-1]+nums[i],nums[i]);
            if(dp[i]>ans){
                ans=dp[i];
            }
        }
        return ans;
    }
};

392.判断子序列

思路:先说说比较好想到的双指针法,标答里没写,即用两个指针i,j分别指向s和t,然后从头开始往后匹配,如果相等,则将i++,开始匹配t的下一位,不管相不相等每次匹配后都要j++,即t需要从头匹配到结尾,如果遍历完t后s没有遍历完,则说明不是子串,否则是子串。时间复杂度O(n)。

cpp 复制代码
class Solution {
public:
    bool isSubsequence(string s, string t) {
        int i,j;
        for(i=0,j=0;i<s.size(),j<t.size();j++){
            if(s[i]==t[j]){
                i++;
            }
        }
        return i==s.size();
    }
};

然后是dp方法,本题是编辑距离的入门 ,dp五部曲:dp数组,dpij表示s以i-1结尾,t以j-1结尾的相同子序列长度,用i-1和j-1的原因同最长子数组那题,方便初始化;递推公式,如果si-1与tj-1相等,则说明找到了一个相同字符,则dp[i][j]=dp[i-1][j-1]+1,如果不相等,说明t需要删除这个元素,继续往后匹配,即删除tj-1,则这时的结果即为前一位的匹配结果dpij-1可以发现这里和相同子序列那题一样,只不过本题只能删t的元素;初始化,全部为0;遍历顺序,顺序遍历;举例略。时间复杂度O(mn)。双指针的复杂度低一点。

cpp 复制代码
class Solution {
public:
    bool isSubsequence(string s, string t) {
        vector<vector<int>> dp(s.size()+1,vector<int>(t.size()+1,0));
        for(int i=1;i<=s.size();i++){
            for(int j=1;j<=t.size();j++){
                if(s[i-1]==t[j-1]){
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else{
                    dp[i][j]=dp[i][j-1];
                }
            }
        }
        return dp[s.size()][t.size()]==s.size();
    }
};
相关推荐
Kurisu_红莉栖几秒前
前缀和的另外一种用法,前缀和分解
算法
88号技师12 分钟前
2026年2月一区SCI-交叉传播优化算法Propagation Alongside Crossover-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
悠仁さん12 分钟前
数据结构 图(代码实现篇 C语言版)
数据结构·算法·图论
aini_lovee14 分钟前
多智能体粒子群优化(Multi-Agent Particle Swarm Optimization, MAPSO)
算法
周末也要写八哥19 分钟前
贪心法求经典算法题——最低加油次数
算法
插件开发38 分钟前
vs2015 cuda c++ 线程号的计算详解
开发语言·c++·算法
有点。38 分钟前
C++(前缀和与差分)
c++·算法
仍然.1 小时前
算法题目---BFS解决最短路问题
算法·宽度优先
渡众机器人1 小时前
第八届全球校园人工智能算法精英大赛-算法应用赛-空地协同侦排挑战赛规则
人工智能·算法
wayz111 小时前
Overlap:HWMA(Holt-Winter移动平均线)技术指标详解
算法·金融·数据分析·量化交易·特征工程