力扣爆刷第80天--动态规划一网打尽子序列一维二维连续不连续变体

本文主要是介绍力扣爆刷第80天--动态规划一网打尽子序列一维二维连续不连续变体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

力扣爆刷第80天–动态规划一网打尽子序列一维二维连续不连续变体

文章目录

      • 力扣爆刷第80天--动态规划一网打尽子序列一维二维连续不连续变体
      • 零、总结
      • 一、1035.不相交的线
      • 二、53. 最大子序和
      • 三、392.判断子序列
      • 四、115.不同的子序列

零、总结

今天也是子序列的一天,但和上一期不同的是都是变体,也分为一维、二维、连续、非连续四种题型。
另外就是做子序列相关的题目一定要考虑好定义以后就使用实例自己推导一下,把结果展现出来,然后再看看能否推导出递推公式或者看看递推公式是否匹配。

一、1035.不相交的线

题目链接:https://leetcode.cn/problems/uncrossed-lines/description/
思路:本题不相交的线其实是求最长重复子序列,只是把题目的问法稍微改动了一点,但本质没有变,子序列具体的四种类型上一期有讲,本期不再赘述。
定义dp[i][j]表示区间nums1[0, i]和区间nums2[0, j]中以nums1[i]和nums2[j]为结尾的最长重复子序列的长度,那么如果nums1[i]==num2s[j],dp[i][j]自然可以从dp[i-1][j-1]推出,为dp[i][j] = dp[i-1][j-1] + 1;
如果nums1[i] != num2s[j],那么最长的长度要延续之前的长度,dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);

class Solution {public int maxUncrossedLines(int[] nums1, int[] nums2) {int[][] dp = new int[nums1.length+1][nums2.length+1];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. 最大子序和

题目链接:https://leetcode.cn/problems/maximum-subarray/
思路:本题求的是最大和的连续子数组,是一维的,和上一期中的最长连续递增子序列是一类题目,只不过算个变体,改变了问法,但解题的方法没有变,依然是定义dp[i]表示为nums[0, i]中以nums[i]为结尾的连续子数组的最大和,那么对于每一个元素来说,是否加到上一个连续子数组的结尾,取决于加上后,和的值是否变大,不变大就另起炉灶,由此可以得到递推公式:dp[i] = Math.max(nums[i], dp[i-1]+nums[i]);

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

贪心:
另外本题使用贪心也可以做,求最大连续子数组的和,只要连续子数组的和大于0,就可以相加,如果小于0,便新开一个子数组。

class Solution {public int maxSubArray(int[] nums) {int sum = 0, max = Integer.MIN_VALUE;for(int i = 0; i < nums.length; i++) {sum += nums[i];max = Math.max(sum, max);if(sum < 0) {sum = 0;}}return max;}
}

三、392.判断子序列

题目链接:https://leetcode.cn/problems/is-subsequence/
思路:本题是判断s是否是t的子序列,那么也有是一个变体,即s是连续,t非连续,上一期的是s与t都连续,或者都不连续,且看本题如何解决。
定义dp[i][j]表示,s[0, i] 和 t[0, j]中以s[i]为结尾,且以t[j]为结尾,是否为其子序列,如果s[i]==t[j]根据定义,延续dp[i-1][j-1]的状态,如果s[i] != t[j],应该延续,s[i]与t[j-1]的状态,如s = “b”, t = “abc” , 求dp[1][3],b与c不等,应该继承 “b” 与 "ab"的状态。

class Solution {public boolean isSubsequence(String s, String t) {if(s.length() > t.length()) return false;if(s.length() == 0) return true;boolean[][] dp = new boolean[s.length()+1][t.length()+1];Arrays.fill(dp[0], true);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];}else{dp[i][j] = dp[i][j-1];}}}return dp[s.length()][t.length()];}
}

双指针:
下面的写法丑陋了一些,但也是双指针,调整了t的遍历位置。

class Solution {public boolean isSubsequence(String s, String t) {int len = 0, k = 0;for(int i = 0; i < s.length(); i++) {for(int j = k; j < t.length(); j++) {if(s.charAt(i) == t.charAt(j)) {len++;k = j+1;break;}}}return len == s.length();}
}

四、115.不同的子序列

题目链接:https://leetcode.cn/problems/distinct-subsequences/
思路:本题也是变体,s不连续,t连续,和上一题是类似的,但是求的目标变成了组合数,依然定义为dp[i][j]表示为s[0, i]和t[0, j]以s[i]和t[j]为结尾,t出现在s中的组合数,那么当s[i]==t[j]时,不光可以记录下s[i-1]和t[j-1]的组合数,也可以记录下s[i-1]和t[j]的组合数,不等时,只需要记录s[i-1]与t[j]的组合数,具体可以简单推导一下。

class Solution {public int numDistinct(String s, String t) {int[][] dp = new int[s.length()+1][t.length()+1];for(int i = 0; i < s.length(); i++) {dp[i][0] = 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] + dp[i-1][j];}else {dp[i][j] = dp[i-1][j];}}}return dp[s.length()][t.length()];}
}

这篇关于力扣爆刷第80天--动态规划一网打尽子序列一维二维连续不连续变体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750521

相关文章

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

PostgreSQL 序列(Sequence) 与 Oracle 序列对比差异分析

《PostgreSQL序列(Sequence)与Oracle序列对比差异分析》PostgreSQL和Oracle都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异,... 目录PostgreSQL 序列(Sequence) 与 oracle 序列对比一 基本语法对比1.1 创建序

Python Selenium动态渲染页面和抓取的使用指南

《PythonSelenium动态渲染页面和抓取的使用指南》在Web数据采集领域,动态渲染页面已成为现代网站的主流形式,本文将从技术原理,环境配置,核心功能系统讲解Selenium在Python动态... 目录一、Selenium技术架构解析二、环境搭建与基础配置1. 组件安装2. 驱动配置3. 基础操作模

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删