代码随想录Day57

news2024/12/29 13:07:05

1143.最长公共子序列

给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例 1:

输入:text1 = "abcde", text2 = "ace" 
输出:3  
解释:最长公共子序列是 "ace" ,它的长度为 3 。

思路:

1.Day56的求重复子数组本质上是求最长连续子序列,而本题实际上就是求最长子序列,又回到了要不要看连续的问题,但大体思路实际上与求重复子数组一致,有了前一道题的基础,本题至少能够有思路了。

2.首先想dp数组的含义,dp[i][j]表示text1中区间为[0 , i - 1]和text2中区间为[0, j - 1]的两个字符串的最长公共子序列长度。

3.然后想递推公式。我们通过比较当前的text1[i]与text2[j]划分出两种情况:相等或不等。相等的情况下,那么直接在dp[i - 1][j - 1]的基础之上加1即可;如果不相等,那么就在dp[i - 1][j]和dp[i][j - 1]中取最大的,相当于就是分别在text1中取[0, i -2]和text2中取[0, j - 1],与在text1中取[0, i -1]和text2中取[0, j - 2]拿到的两个最大公共子序列长度求最大值

4.然后想初始化,dp[i][0]与dp[0][j]根据dp数组定义来看是没有意义的,但方便递推我们初始化为0,而其他的我们也一并初始化为0即可。

5.最后想遍历顺序,如果我们以i为行以j为列画出一个二维矩阵,通过递推公式不难发现dp[i][j]能够由dp[i - 1][j - 1],dp[i][j - 1],dp[i - 1][j]推导出来,即能够从左上方推导出来,因此我们的遍历顺序是从上向下,从左往右(即对于i和j都是从小到大遍历)。

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        //dp数组表示对于[0, i - 1]的text1,[0, j - 1]的text2的最长公共子序列
        vector<vector<int>> dp(text1.size() + 1, vector(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;
                }
                //比较的两个字符不相等,则看[0,i - 2]的text1与[0, j - 1]的text2的最长公共子序列
                //和[0,i - 1]的text1与[0, j - 2]的text2的最长公共子序列
                else{
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        return dp[text1.size()][text2.size()];
    }
};

启发:

1.通过本题在看完讲解和联系之前的一系列动规题目后,恍然了dp数组在本系列问题中为什么要选择二维,因为实际上以前的大部分题目理论上来说也都是二维,用一个维度代表元素一个维度代表状态,只是我们简化后可以只用一维表示状态;而在本系列问题中尤其是涉及到两个数组进行比较,此时我们需要分别表示两个数组的不同状态,此时一维是完全不可能做到的,因此必须得使用二维。因此dp数组的维度一定程度上是根据我们所需要记录的状态来决定的

2.通过抽象画出二维矩阵再结合递推公式,我们可以很轻松的得出我们的遍历顺序,在这之前可能大多数时候是想当然的想出递推公式,经过这一题后发现原来可以通过具体的矩阵来顺理成章推出遍历顺序。

1035.不相交的线

在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。

现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足:

 nums1[i] == nums2[j]
且绘制的直线不与任何其他连线(非水平线)相交。
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。

以这种方法绘制线条,并返回可以绘制的最大连线数。

示例 1:


输入:nums1 = [1,4,2], nums2 = [1,2,4]
输出:2
解释:可以画出两条不交叉的线,如上图所示。 
但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相交。
示例 2:

输入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
输出:3
示例 3:

输入:nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
输出:2

思路:

1.本题在刚做完前一道题的时候来看会发现实际上就是上一道题,但既然是分析思路那自然得站在没有看过上一道题的基础上来看。本题很容易被所谓的连线给绕进去,会一直考虑如何避免连线相交。

但实际上在有了前面子序列题目的基础后我们不难发现,所谓的连线不能相交实际上就是保证元素顺序一定,例如示例2中nums1[0] = nums2[2] = 2,nums1[1] = nums2[4] =5,对于两个数组中的5都要保证是在1之后,不能让nums[1]的5与nums2[1]的5相连,因为此时nums2中5没有在1之后。

所以实际上就是保证连线元素的顺序一定,和前面求子序列的情况一比较就发现实际上是一模一样的。所以本题代码实际上和上一题也在除了命名之外完全一致。

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()];
    }
};

启发:

1.本题实际上真的很容易绕进直线相交的泥潭里去然后出不来,然而看破后会发现直线相交实际上只是子序列套的一层壳,要学会通过现象看本质。

53.最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

思路:

1.本题实际上是贪心算法中的一道题,那时候已经用贪心算法解决了,回过头来用动规看这道题时发现贪心思路其实时给了自己很大帮助。

2.首先想dp数组含义,dp[i]表示数组中以i结尾的最大子数组和。

3.然后想递推公式,显然对于当前元素,要么选择在前面元素连续和基础上加上当前元素,要么直接从当前元素开始重新计算,因此dp[i] = max(dp[i - 1] + nums[i], dp[i])

4.然后想初始化,通过递推公式可以看出是通过dp[0]推导出后面所有元素,而dp[0]显然是初始化为nums[0],后面的全部初始化为0即可,不影响最终结果。

5.最后想遍历顺序,很明显本题是从前往后遍历。

贪心:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int count = 0;
        int result = INT_MIN;

        for(int i = 0; i < nums.size(); i++){
            count += nums[i];
            result = max(result, count);
            //如果连续和已经小于0,那么重置
            if(count <= 0){
                count = 0;
            }
        }
        return result;
    }
};

动规:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size() == 1) return nums[0];

        vector<int> dp(nums.size(), 0);
        int result = nums[0];
        dp[0] = nums[0];

        for(int i = 1; i < nums.size(); i++){
            dp[i] = max(dp[i - 1] + nums[i], nums[i]);
            result = max(result, dp[i]);
        }

        return result;
    }
};

启发:

1.本题再一次提醒自己关于最后返回的结果,实际上是和dp数组的含义紧密相连的,有的题目dp数组最后的元素实际上就是我们返回的结果,但有的题目(例如本题),结果并不一定是在dp数组的最后元素位置取得,因此我们一定要根据dp数组的含义和具体题目具体分析。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/442047.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版&#xff08;1.104.0&#xff09;通过异步方式初始化地球&#xff0c;加载影像以及高程图层 遇到问题初始化底图初始化高程&#xff08;监听载入完成事件&#xff0c;开启关闭高程&#xff09;初始化 3dtile Cesium 最新版&#xff08;1.104.0&#xff09;变…

2021地理设计组二等奖:基于地理大数据的南昌中心城区空间功能感知与分区

一、设计背景及意义 随着经济快速发展&#xff0c;城市功能类型也越来越多&#xff0c;在空间上逐渐聚集和演化&#xff0c;形成了居住区&#xff0c;商业区等城市功能区&#xff0c;而这些功能区没有明显边界&#xff0c;确定困难&#xff0c;如使用传统人力调查方法费时费力…

PHP快速入门16-用curl发起POST和GET的请求

文章目录 前言curl介绍发送GET请求发送POST请求其他选项 总结 前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP快速入门与实战 在Web开发中&#xff0c;经常需要与其他服务器进行数据交互。而现在&#xff0c;绝大多数的接口都是基于HTTP协议的&#xff0c;因此我们需要学会…

Spring MVC的功能

1. 连接功能 1.1几种注解 RequestMapping最常用的注解之一&#xff0c;作用是用来路由注册&#xff08;注册接口的路由映射&#xff09;&#xff0c;即可修饰类也能修饰方法&#xff0c;默认情况下的RequestMapping即可接收Get请求也可以接收Post请求。也可以通过设置method来…

数据通信基础 - 数字传输系统(T1、E1)

文章目录 1 概述2 载波标准&#xff08;E1、T1&#xff09;2.1 T12.2 E1 3 扩展3.1 网工软考真题 1 概述 2 载波标准&#xff08;E1、T1&#xff09; 名称速率 Mbps信道个数每个语音信道的数据速率使用国家T11.5442456Kb/s美国、日本E12.0483264Kb/s欧洲、中国 2.1 T1 语音信…

5g网络变压器的特点与优势分析

5g网络变压器的特点与优势分析 5G网络变压器相比于2.5G和3G网络变压器&#xff0c;具有以下的特点和优势&#xff1a; 更高的频率&#xff1a;5G网络变压器可以支持更高的频率&#xff0c;从而实现更高的数据传输速率和更低的延迟。 更小的尺寸&#xff1a;5G网络变压器采用了…

为什么越来越多的网站选择海外主机?探究原因!

主机已成为网站托管的常用方式&#xff0c;但近年来越来越多的网站选择海外主机。这是为什么呢?在本文中&#xff0c;我们将探究海外主机的优点&#xff0c;并解释为什么越来越多的网站选择它们。 一、海外主机的优点 1、成本更低 海外主机的成本比独立主机低&#xff0c;因为…

文件系统和日志分析

文件系统 文件是存储在硬盘上的&#xff0c;硬盘的最小存储单位叫做"扇区”(sector)每个扇区存储512字节。一般连续八个扇区组成一个"块"(block)&#xff0c;一个块是4K大小&#xff0c;是文件存取的最小单位。操作系统读取硬盘的时候&#xff0c;是一次性连续…

哪个牌子手持洗拖一机好?热门洗地机盘点

在家居清洁中&#xff0c;越来越多的家庭选择了通过智能清洁家电来完成地面的清洁工作&#xff0c;其中洗地机时最受大家青睐的清洁工具&#xff0c;它不仅可以提高我们的清洁效率&#xff0c;还可以减轻清洁时的劳动强度。不过&#xff0c;不同品牌之间的产品的差距也是大有不…

MobPush Android SDK 集成指南

开发工具&#xff1a;Android Studio 集成方式&#xff1a;Gradle在线集成 安卓版本支持&#xff1a;minSdkVersion 19 集成准备 注册账号 使用PushSDK之前&#xff0c;需要先在MobTech官网注册开发者账号&#xff0c;并获取MobTech提供的AppKey和AppSecret&#xff0c;详情可…

世界大学机械工程TOP10,国内大学哪家强?

就在前不久世界大学的排名已经发布&#xff0c;机械工程学科是工科类学科当中代表学科之一&#xff0c;相信很多小伙伴是非常想要了解的。那么&#xff0c;我给大家介绍一下2023年QS世界大学&#xff08;机械工程&#xff09;学科排名。 本次排名比较分析了包括世界93个地区的…

智能洗地机哪个牌子更好用?好用不贵的洗地机推荐

近年来&#xff0c;智能家居产品越来越多&#xff0c;从一开始的扫地机器人到吸尘器再到后来的蒸汽拖把再到现在的洗地机&#xff0c;这些智能化清洁工具&#xff0c;不仅为我们节省了清洁的时间还拥有很好的清洁效果。其中洗地机是近年来最受大家青睐的清洁工具&#xff0c;那…

【Vulnhub】之symfonos1

一、 部署方法 在官网上下载靶机ova环境&#xff1a;https://download.vulnhub.com/symfonos/symfonos1.7z使用VMware搭建靶机环境攻击机使用VMware上搭建的kali靶机和攻击机之间使用NAT模式&#xff0c;保证靶机和攻击机放置于同一网段中。 二、 靶机下载安装 靶机下载与安…

电阻的选型

记点、 NOTE:通用的元器件选型步骤&#xff1a; A&#xff1a;明晰元器件的关机参数 B&#xff1a;结合具体的应用确定跟该应用最直接关联的关键参数 1、电阻的关键参数 2、电阻在电路的作用&#xff1a; 主要是用来是用来稳定和调节电流和电压。可作为分流器和分压器。也可…

ubuntu22.04安装nvidia驱动

ubuntu22.04安装nvidia驱动 环境前言直通显卡ubuntu2204虚拟机配置禁用默认显卡驱动安装显卡驱动查看显卡状态参考文章 环境 ESXi-7.0U3l ubuntu22.04 前言 在第一次成功之后&#xff0c;重启了虚拟机&#xff0c;失败了很多次&#xff0c;重装了n次系统和驱动&#xff0c;但…

452. 用最少数量的箭引爆气球

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一…

DAX:概述ALL函数

简单的说&#xff0c;当ALL用作表函数时&#xff0c;忽略应用到表上的任何过滤器&#xff0c;并返回数据表&#xff1b;当ALL用作CALCULATE和CALCULATETABLE函数中修饰器时&#xff0c;ALL函数从扩展表中移除已经应用的过滤上下文。 注意自动存在(auto-eixist)对ALL()函数的影响…

前后端目前进展

进展 前端第一个vue2第二个vue2&#xff08;用来复盘结果报错&#xff09;第三个vue2 后端第一个django&#xff08;本地&#xff09;第二个django&#xff08;GPU&#xff09; 前后端连接 前端 (前端创建方式/流程详细见我的博客vue2创建) 第一个vue2 项目名&#xff1a;te…

戴尔G3 Ubuntu18.04双系统安装

ROS学习需要使用Linux系统&#xff0c;首先就是Ubuntu&#xff0c;我选择的是18.04.6这个版本&#xff0c;因为后面我要使用以Jetson Nano为主控的Jetbot进行ROS编程&#xff0c;Jetbot所带的出厂镜像就是18.04&#xff0c;为了方便程序移植&#xff0c;以及减少不必要的麻烦。…

MATLAB | 绘图复刻(八) | 堆叠柱状图+哑铃图

本次复刻的是Nature Communications中Friedman, S.T., Muoz, M.M. A latitudinal gradient of deep-sea invasions for marine fishes. Nat Commun 14, 773 (2023). https://doi.org/10.1038/s41467-023-36501-4的Fig1图像&#xff1a; 复刻效果&#xff1a; 文章可在如下网站下…