首页 > 其他分享 >leetcode 刷题day42动态规划Part11(1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列)

leetcode 刷题day42动态规划Part11(1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列)

时间:2024-10-15 15:19:29浏览次数:3  
标签:1143 nums int length 序列 递推 子序 dp

1143.最长公共子序列

思路:718. 最长重复子数组两个数组对应相同且连续,所以递推公式是dp[i-1][j-1]+1。最长公共子序列不要求连续但要求相对顺序,差别主要在于递推公式。

对于该题主要有两大情况: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]不相同,就取dp[i - 1][j]和dp[i][j - 1]最长公共子序列最大的。即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

代码如下:

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        char[] char1=text1.toCharArray();
        char[] char2=text2.toCharArray();
        int[][] dp=new int[char1.length+1][char2.length+1];
        for(int i=0;i<=char1.length;i++){
            dp[i][0]=0;
        }
        for(int j=0;j<=char2.length;j++){
            dp[0][j]=0;
        }
        for(int i=1;i<=char1.length;i++){
            for(int j=1;j<=char2.length;j++){
                if(char1[i-1]==char2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
                else dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
            }
        }
        return dp[char1.length][char2.length];
    }
}

1035.不相交的线

思路:这个题目乍一看没有思路,看完题解后发现该题等同于计算A和B的最长公共子序列(相对顺序不变)的长度。

所以解题代码和上一题完全相同,代码如下:

class Solution {
    public int maxUncrossedLines(int[] nums1, int[] nums2) {
        int[][] dp=new int[nums1.length+1][nums2.length+1];
        for(int i=0;i<=nums1.length;i++){
            dp[i][0]=0;
        }
        for(int j=0;j<=nums2.length;j++){
            dp[0][j]=0;
        }
        for(int i=1;i<=nums1.length;i++){
            for(int j=1;j<=nums2.length;j++){
                if(nums1[i-1]==nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
                else dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
            }
        }
        return dp[nums1.length][nums2.length];
    }
}

53. 最大子序和

思路:使用贪心算法,记录累加和的最大值,且一旦累加和小于等于0则重新累加。

动规五部曲如下:

1、确定dp数组(dp table)以及下标的含义
dp[i]:包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]。

2、确定递推公式
dp[i]有两个方向可以推出来:

  • dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和
  • nums[i],即:重新计算当前连续子序列和
    取最大的,所以dp[i] = max(dp[i - 1] + nums[i], nums[i]);

3、dp数组如何初始化
dp[i]依赖于dp[i - 1]的状态,dp[0]就是递推公式的基础。
dp[0]应为nums[0]即dp[0] = nums[0]。

4、确定遍历顺序
递推公式中dp[i]依赖于dp[i - 1]的状态,需要从前向后遍历。

5、举例推导dp数组

代码如下:

class Solution {
    public int maxSubArray(int[] nums) {
        int[] dp=new int[nums.length];
        int result=nums[0];
        dp[0]=nums[0];
        for(int i=1;i<nums.length;i++){
            dp[i]=Math.max(dp[i-1]+nums[i],nums[i]);
            if(result<dp[i]) result=dp[i];
        }
        return result;
    }
}

392.判断子序列

双指针解法:

class Solution {
    public boolean isSubsequence(String s, String t) {
        if(s.length()==0) return true;
        char[] charS=s.toCharArray();
        char[] charT=t.toCharArray();
        int i=0;
        for(int j=0;j<charT.length;j++){
            if(i==charS.length) break;
            if(charS[i]==charT[j]) i++;
        }
        if(i==charS.length) return true;
        else return false;
    }
}

这道题是编辑距离的入门题目,只需要计算删除的情况,不用考虑增加和替换的情况。掌握本题的动态规划解法是对后面要讲解的编辑距离的题目打下基础。

动态规划五部曲分析如下:

1、确定dp数组(dp table)以及下标的含义
dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]。

2、确定递推公式
在确定递推公式的时候,if (s[i - 1] != t[j - 1]),相当于t要删除元素,继续匹配。if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;,if (s[i - 1] != t[j - 1]),此时相当于t要删除元素,把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是看s[i - 1]与 t[j - 2]的比较结果,即:dp[i][j] = dp[i][j - 1];
(这里不是很懂,需要多思考一下)

3、dp数组如何初始化
从递推公式可以看出dp[i][j]都是依赖于dp[i - 1][j - 1] 和 dp[i][j - 1],所以dp[0][0]和dp[i][0]是一定要初始化的。

4、确定遍历顺序
dp[i][j]依赖于dp[i - 1][j - 1] 和 dp[i][j - 1],遍历顺序应该是从上到下,从左到右。

5、举例推导dp数组

代码如下:

class Solution {
    public boolean isSubsequence(String s, String t) {
        int[][] dp=new int[s.length()+1][t.length()+1];
        for(int i=1;i<=s.length();i++){
            for(int j=1;j<=t.length();j++){
                if(s.charAt(i-1)==t.charAt(j-1)) dp[i][j]=dp[i-1][j-1]+1;
                else dp[i][j]=dp[i][j-1];
            }
        }
        if(dp[s.length()][t.length()]==s.length()) return true;
        else return false;
    }
}

标签:1143,nums,int,length,序列,递推,子序,dp
From: https://blog.csdn.net/m0_51007517/article/details/142910640

相关文章

  • shiro 反序列化漏洞
    shiro反序列化漏洞Shiro-550漏洞原理影响版本:ApacheShiro<1.2.4特征判断:返回包中包含rememberMe=deleteMe字段。为了让浏览器或服务器重启后用户不丢失登录状态,Shiro支持将持久化信息序列化并加密后保存在Cookie的rememberMe字段中,下次读取时进行解密再反序列化。Pa......
  • 计量经济学(四)——序列相关性的检验与修正
    序列相关性(SerialCorrelation)是指在时间序列或截面数据的回归模型中,误差项之间存在相关性。这种现象意味着当前误差项的值会受到前期误差项的影响,误差项之间并不是独立的。这与经典线性回归模型假设的误差项是独立同分布的(i.i.d.)违背了高斯-马尔可夫定理(Gauss-MarkovTheorem)中......
  • 【机器学习(十)】时间序列—Holt-Winters方法—Sentosa_DSML社区版
    @目录一、Holt-Winters算法原理(一)加法模型(一)乘法模型(三)阻尼趋势二、HoltWinters算法优缺点优点缺点三、Python代码和Sentosa_DSML社区版算法实现对比(一)数据读入和统计分析(二)数据预处理(三)模型训练和模型评估(四)模型可视化四、总结一、Holt-Winters算法原理......
  • 针对不同类型的数据,哪些Python可视化库更适合处理时间序列数据?
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;推荐专栏《10天学会使用asp.net编程AI大模型》,目前已完成所有内容。一顿烧烤不到的费用,让人能紧跟时代的浪潮。从普通网站,到公众号、小程序,再到AI大模型网站。干货满满。学成后可......
  • 【题解】P3917 异或序列
    传送门也算是一个有关于异或的小trick吧,简单记录一下。可以维护原序列的前缀异或和\(sum\),于是原题答案贡献变为\(\sum\limits_{i=1}^n\sum\limits_{j=i}^nsum_j\oplussum_{i-1}\)。变形一下为\(\sum\limits_{i=0}^{n-1}\sum\limits_{j=1}^{i+1}sum_i\oplussum_{j}......
  • DBPM: 增强时间序列对比学习:一种动态坏对挖掘方法《Towards Enhancing Time Series Co
    今天是2024年10月12日,思路枯竭,还是论文看的太少了,继续看论文.论文:TowardsEnhancingTimeSeriesContrastiveLearning:ADynamicBadPairMiningApproach或者是:TowardsEnhancingTimeSeriesContrastiveLearning:ADynamicBadPairMiningApproachGitHub:https://git......
  • 最长递增子序列
    最长递增子序列300.最长递增子序列普通解法#include<vector>usingnamespacestd;classSolution{public://时间复杂度O(n^2)intlengthOfLIS(vector<int>&nums){intn=nums.size();//dp[i]:以nums[i]结尾的最长递增子序列......
  • 代码随想录算法训练营第三十一天|455.分发饼干 376. 摆动序列 53. 最大子序和
    455.分发饼干假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j,都有一个尺寸s[j] 。如果s[j] >=g[i],我们可以将这个饼干j分配给孩子i,......
  • 题解:[HNOI2009] 双递增序列
    ProblemLink[HNOI2009]双递增序列题目描述给定一个长度为\(n\)的序列(\(n\)为偶数),求是否可以把序列分成\(2\)个长度为\(\frac{n}{2}\)的递增序列。Solution首先想到定义\(f_i\)为一个序列以\(a_i\)结尾时另一个序列末尾最小值。但这样定义状态信息是不够的,考虑......
  • 牛客AB33.相差不超过k的最多数 (滑动窗口) 牛客.DP最长公共子序列牛客.春游主持人调度
    目录牛客AB33.相差不超过k的最多数 (滑动窗口) 牛客.DP最长公共子序列牛客.春游主持人调度(二)牛客AB33.相差不超过k的最多数 (滑动窗口) 和之前那个空调吹风属于一道题的类型,当然滑动窗口,最大值-最小值,然后<=p即可也可以双指针来取寻找最大值和最小值impor......