力扣练习题(2024/4/17)

1 最长递增子序列

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的

子序列

。 

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

示例 2:

输入:nums = [0,1,0,3,2,3]
输出:4

示例 3:

输入:nums = [7,7,7,7,7,7,7]
输出:1

提示:

  • 1 <= nums.length <= 2500
  • -104 <= nums[i] <= 104

思路:

我们使用动态规划的方法来解决这个问题,具体步骤如下:

  1. 初始化:我们创建一个与原始数组长度相同的动态规划数组 dp,其中 dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度,初始时都设为1。这是因为每个单独的元素都是一个长度为1的上升子序列。

  2. 遍历:我们从数组的第二个元素开始,遍历整个数组。对于当前元素 nums[i],我们再次从开头开始遍历到当前元素之前的所有元素 nums[j]

  3. 状态转移

    位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。

    所以:if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);

    如果 nums[i] 大于 nums[j],说明 nums[i] 可以接在 nums[j] 后面形成一个更长的上升子序列。这时我们更新 dp[i] 为 dp[j] + 1 的最大值。这表示以 nums[i] 结尾的最长上升子序列的长度,取决于前面某个元素能够构成的最长上升子序列的长度加上当前元素。

  4. 最大长度:在遍历过程中,我们始终保持一个变量 longest_length 来记录已经找到的最长上升子序列的长度。这个变量始终取 dp 数组中的最大值。

  5. 结果返回:最终,遍历完成后 longest_length 就是整个数组的最长上升子序列的长度

代码:

class Solution {
public:int lengthOfLIS(vector<int>& nums) {// 如果数组大小小于等于1,则直接返回数组大小,因为最长上升子序列最短也是1if (nums.size() <= 1) return nums.size();// 创建动态规划数组,初始值都为1,表示每个元素自身构成的最长上升子序列长度至少是1vector<int> dp(nums.size(), 1);// 用于存储最终的最长上升子序列的长度int longest_length = 1; // 最短的上升子序列长度是1,即单独一个元素// 遍历数组for (int i = 1; i < nums.size(); i++) {// 内层循环,遍历当前元素之前的元素for (int j = 0; j < i; j++) {// 如果当前元素 nums[i] 大于之前的某个元素 nums[j],可以构成一个更长的上升子序列if (nums[i] > nums[j]) {// 更新 dp[i] 为 dp[j] + 1 的最大值,表示以当前元素 nums[i] 结尾的最长上升子序列长度dp[i] = max(dp[i], dp[j] + 1);}}// 更新最长上升子序列的长度,取当前 dp 数组中的最大值longest_length = max(longest_length, dp[i]);}// 返回最终的最长上升子序列长度return longest_length;}
};

2最长连续递增序列

给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。

连续递增的子序列 可以由两个下标 l 和 rl < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。

示例 1:

输入:nums = [1,3,5,4,7]
输出:3
解释:最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。 

示例 2:

输入:nums = [2,2,2,2,2]
输出:1
解释:最长连续递增序列是 [2], 长度为1。

提示:

  • 1 <= nums.length <= 104
  • -109 <= nums[i] <= 109

思路:

dp[i]:以下标i为结尾的连续递增的子序列长度为dp[i]

注意这里的定义,一定是以下标i为结尾,并不是说一定以下标0为起始位置。

  1. 初始化:首先,我们需要明确最长连续递增子序列的概念,即在一个序列中找到最长的连续递增的子序列。为了解决这个问题,我们采用动态规划的方法。我们创建一个长度与原始数组相同的动态规划数组 dp,其中 dp[i] 表示以 nums[i] 结尾的最长连续递增子序列的长度。初始时,我们将所有的 dp[i] 都设为1。这是因为每个单独的元素都是一个连续递增子序列。

  2. 遍历:接下来,我们从数组的第二个元素开始遍历整个数组。在遍历过程中,我们关注的是当前元素 nums[i] 与前一个元素 nums[i-1] 的关系。

  3. 状态转移:如果 nums[i] 大于 nums[i-1],说明 nums[i] 可以接在 nums[i-1] 后面形成一个更长的连续递增子序列。因此,我们将 dp[i] 更新为 dp[i-1] + 1。这表示以 nums[i] 结尾的最长连续递增子序列的长度取决于前面的某个元素能够构成的最长连续递增子序列的长度加上当前元素。

  4. 最大长度:在遍历过程中,我们始终保持一个变量 result 来记录已经找到的最长连续递增子序列的长度。这个变量始终取 dp 数组中的最大值。

  5. 结果返回:最终,遍历完成后,result 就是整个数组的最长连续递增子序列的长度。

代码:

class Solution {
public:int findLengthOfLCIS(vector<int>& nums) {if (nums.size() == 0) return 0;int result = 1;  // 最短连续递增子序列的长度是1,即单独一个元素vector<int> dp(nums.size(), 1);  // 创建动态规划数组,初始值都为1,表示每个元素自身构成的最长连续递增子序列长度至少是1for (int i = 1; i < nums.size(); i++) {if (nums[i] > nums[i - 1]) {  // 如果当前元素大于前一个元素,说明可以构成连续递增子序列dp[i] = dp[i - 1] + 1;  // 更新 dp[i] 为 dp[i-1] + 1,表示以当前元素结尾的最长连续递增子序列长度}if (dp[i] > result) result = dp[i];  // 更新最长连续递增子序列的长度,取当前 dp 数组中的最大值}return result;  // 返回最终的最长连续递增子序列长度}
};

3 最长重复子数组

给两个整数数组 nums1 和 nums2 ,返回 两个数组中 公共的 、长度最长的子数组的长度 

示例 1:

输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
输出:3
解释:长度最长的公共子数组是 [3,2,1] 。

示例 2:

输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
输出:5

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 100

思路:

  1. 创建一个二维动态规划数组 dp,其中 dp[i][j] 表示 nums1 的前 i 个元素和 nums2 的前 j 个元素形成的最长公共子数组的长度。
  2. 初始化 dp 数组,将所有元素初始化为0。
  3. 遍历 nums1 和 nums2 的每个元素,分别用 i 和 j 表示当前位置。
  4. 如果 nums1[i - 1] 等于 nums2[j - 1],说明当前位置的元素相等,那么更新 dp[i][j] = dp[i - 1][j - 1] + 1
  5. 在遍历过程中不断更新记录最长公共子数组长度的变量 result,如果 dp[i][j] 大于 result,则更新 result = dp[i][j]
  6. 最终返回 result,即为两个数组的最长公共子数组的长度。

代码:

// 版本一
class Solution {
public:int findLength(vector<int>& nums1, vector<int>& nums2) {// 创建二维动态规划数组,dp[i][j] 表示 nums1 的前 i 个元素和 nums2 的前 j 个元素形成的最长公共子数组的长度vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0));int result = 0;  // 记录最长公共子数组的长度初始为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;  // 更新当前位置的最长公共子数组长度为前一个位置加1}if (dp[i][j] > result) result = dp[i][j];  // 更新最长公共子数组的长度}}return result;  // 返回最长公共子数组的长度}
};

4最长公共子序列

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

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

  • 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。

两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。

示例 1:

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

示例 2:

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

示例 3:

输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0 。

提示:

  • 1 <= text1.length, text2.length <= 1000
  • text1 和 text2 仅由小写英文字符组成。

思路:

  1. 创建一个二维动态规划数组 dp,其中 dp[i][j] 表示 text1 的前 i 个字符和 text2 的前 j 个字符形成的最长公共子序列的长度。
  2. 初始化 dp 数组,将所有元素初始化为0。
  3. 遍历 text1 和 text2 的每个字符,分别用 i 和 j 表示当前位置。
  4. 如果 text1[i - 1] 等于 text2[j - 1],说明当前位置的字符相等,那么更新 dp[i][j] = dp[i - 1][j - 1] + 1
  5. 如果不相等,取前一个位置的最长公共子序列长度的最大值,即 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
  6. 在遍历过程中不断更新记录最长公共子序列长度的值。
  7. 最终返回 dp[text1.size()][text2.size()],即为两个字符串的最长公共子序列长度。

代码:

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {// 创建二维动态规划数组,dp[i][j] 表示 text1 的前 i 个字符和 text2 的前 j 个字符形成的最长公共子序列的长度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;  // 更新当前位置的最长公共子序列长度为前一个位置加1} else {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);  // 如果不相等,则取前一个位置的最长公共子序列长度的最大值}}}return dp[text1.size()][text2.size()];  // 返回 text1 和 text2 的最长公共子序列长度}
};

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

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

相关文章

Jsp 中的getServletContext全局数据共享

servletContext作用于不同用户之上 1. 一个用户将数据保存到了servletContext中, // getcontext的servlet程序 Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context this.get…

考察自动化立体库应注意的几点

导语 大家好&#xff0c;我是智能仓储物流技术研习社的社长&#xff0c;老K。专注分享智能仓储物流技术、智能制造等内容。 整版PPT和更多学习资料&#xff0c;请球友到知识星球 【智能仓储物流技术研习社】自行下载 考察自动化立体仓库的关键因素&#xff1a; 仓库容量&#x…

windows11 wsl2 ubuntu20.04安装vision mamba并进行测试

windows11 wsl2 ubuntu20.04安装vision mamba 安装流程使用cifar-100测试安装成功 安装流程 vision mamba安装了半天才跑通&#xff0c;记录一下流程在wsl上安装cuda wget https://developer.download.nvidia.cn/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05…

[论文笔记]Root Mean Square Layer Normalization

引言 今天带来论文Root Mean Square Layer Normalization的笔记&#xff0c;论文题目是均方根层归一化。 本篇工作提出了RMSNorm&#xff0c;认为可以省略重新居中步骤。 简介 层归一化对Transformer等模型非常重要&#xff0c;它可以帮助稳定训练并提升模型收敛性&#xf…

NVM下载、NVM配置、NVM常用命令

NVM(nodejs版本管理切换工具)下载、配置、常用命令 0、NVM常用命令 nvm off // 禁用node.js版本管理(不卸载任何东西) nvm on // 启用node.js版本管理 nvm install <version> // 安装node.js的命名 version是版本号 例…

发布!DolphinDB 白皮书正式上线官网!

对广大数据库用户而言&#xff0c;白皮书是极具参考价值的使用指南和学习手册。白皮书不但能深入剖析数据库的基础概念与架构&#xff0c;协助用户了解数据库的工作原理和应用技巧&#xff0c;更提供了丰富的实践案例&#xff0c;帮助用户从中汲取经验&#xff0c;避免在实际应…

【JAVA基础篇教学】第十一篇:Java中字符串操作详解

博主打算从0-1讲解下java基础教学&#xff0c;今天教学第十篇&#xff1a;Java中字符串操作详解。 在 Java 编程中&#xff0c;字符串是一种常见的数据类型&#xff0c;通常用于存储文本信息。Java 提供了丰富的字符串操作方法&#xff0c;可以对字符串进行分割、截取、查找…

【QT进阶】Qt Web混合编程之VS2019 CEF的编译与使用(图文并茂超详细介绍)

往期回顾 【QT入门】Qt自定义控件与样式设计之自定义QLineEdit实现搜索编辑框-CSDN博客 【QT入门】Qt自定义控件与样式设计之自定义QTabWidget实现tab在左&#xff0c;文本水平的效果-CSDN博客【QT进阶】Qt Web混合编程之CEF、QCefView简单介绍-CSDN博客 【QT进阶】Qt Web混合编…

文件msvcr120.dll丢失怎样修复?这三种方法能准确修复msvcr120.dll

小编为大家总结了解决msvcr120.dll文件缺失问题的三种方法&#xff0c;以帮助你快速解决这一难题。首先&#xff0c;我们来看看msvcr120.dll文件为何会出现丢失的情形。 一.msvcr120.dll丢失问题的常见原因包括 病毒感染&#xff1a;病毒或恶意软件侵入电脑有可能会损毁或删除…

【第1节】书生·浦语大模型全链路开源开放体系

目录 1 简介2 内容&#xff08;1&#xff09;书生浦语大模型发展历程&#xff08;2&#xff09;体系&#xff08;3&#xff09;亮点&#xff08;4&#xff09;全链路体系构建a.数据b 预训练c 微调d 评测e.模型部署f.agent 智能体 3 相关论文解读4 ref 1 简介 书生浦语 InternLM…

.net9 AOT编绎生成标准DLL,输出API函数教程-中国首创

1&#xff0c;安装VS2022预览版&#xff08;Visual Studio Preview&#xff09; https://visualstudio.microsoft.com/zh-hans/vs/preview/#download-preview 2&#xff0c;选择安装组件&#xff1a;使用C的桌面开发 和 .NET桌面开发 ------------------------------------- …

SnapGene Mac激活版 分子生物学软件

SnapGene Mac是一款功能全面、操作便捷的综合性分子生物学软件&#xff0c;专为Mac用户打造。它集成了DNA序列编辑、分析、可视化和团队协作等多种功能&#xff0c;为科研人员提供了一个高效、可靠的分子生物学研究工具。 SnapGene Mac激活版下载 在SnapGene Mac中&#xff0c;…

批量插入10w数据方法对比

环境准备(mysql5.7) CREATE TABLE user (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 唯一id,user_id bigint(10) DEFAULT NULL COMMENT 用户id-uuid,user_name varchar(100) NOT NULL COMMENT 用户名,user_age bigint(10) DEFAULT NULL COMMENT 用户年龄,create_time time…

ssm057学生公寓管理中心系统的设计与实现+jsp

学生公寓管理中心系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本学生公寓管理中心系统就是在这样的大环境下诞生&#xff0c;其可以帮助管…

【代码】Python3|Requests 库怎么继承 Selenium 的 Headers (2024,Chrome)

本文使用的版本&#xff1a; Chrome 124Python 12Selenium 4.19.0 版本过旧可能会出现问题&#xff0c;但只要别差异太大&#xff0c;就可以看本文&#xff0c;因为本文对新老版本都有讲解。 文章目录 1 难点解析和具体思路2 注意事项2.1 PDF 资源获取时注意事项2.2 Capabiliti…

asp.net core 依赖注入后的服务生命周期

ASP.NET Core 依赖注入&#xff08;DI&#xff09;容器支持三种服务的生命周期选项&#xff0c;它们定义了服务实例的创建和销毁的时机。理解这三种生命周期对于设计健壯且高效的应用程序非常重要&#xff1a; 瞬时&#xff08;Transient&#xff09;&#xff1a; 瞬时服务每次…

西瓜书学习——第一、二章笔记

[] 什么是机器学习? 研究关于“学习算法”(一类能从数据中学习出其背后潜在规律的算法)的一门学科。 PS:深度学习指的是神经网络那一类学习算法&#xff0c;因此是机器学习的子集。 假设空间和版本空间 举个栗子:假设现已收集到某地区近几年的房价和学校数量数据&#xf…

ChatGPT及GIS、生物、地球、农业、气象、生态、环境科学领域案例

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

SRIO系列-时钟逻辑与复位逻辑

一、前言 上一篇讲述了SRIO协议的基本概念&#xff0c;传输的HELLO帧格式、事务类型等&#xff0c;本篇说一下SRIO IP核的时钟关系。 基本的IP设置可以参考此篇文章&#xff1a;【高速接口-RapidIO】Xilinx SRIO IP 核详解-CSDN博客 二、时钟关系 PHY可以在两个时钟域上运行…

自动驾驶(八十四)---------中间件对比分析

很久没有写博客了&#xff0c;CSDN无故非法删了我第82篇&#xff0c;让我很恼火&#xff0c;一直提不起兴趣重新写一遍第82篇。但回初心&#xff0c;知识需要用自己的语言输出&#xff0c;所以今天对比分析自动驾驶中间件&#xff1a; 1. 中间件介绍 在自动驾驶架构中&#xf…