代码随想录算法训练营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();
    }
};
相关推荐
倒头就睡的小比特9 小时前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!9 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼11 小时前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光12 小时前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark12 小时前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her112 小时前
并查集-听课笔记
笔记·算法·并查集
码流子12 小时前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven12 小时前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark12 小时前
从算法设计模式看编程思维的抽象能力4
算法
2601_9622186113 小时前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法