代码随想录算法训练营第五十六天_第九章_动态规划 | 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

news2024/11/19 18:31:58

LeetCode 300.最长递增子序列

给你一个整数数组 nums ,返回其中最长递增子序列的长度。

视频讲解https://www.bilibili.com/video/BV1ng411J7xP文章讲解 https://programmercarl.com/0300.%E6%9C%80%E9%95%BF%E4%B8%8A%E5%8D%87%E5%AD%90%E5%BA%8F%E5%88%97.html

  • 思路:
    • dp数组含义:dp[i]表示数组下标[0, i]中,以nums[i]结尾的最长递增子序列的长度
    • 递推公式:
      • 从0到 i - 1各个位置的最长递增子序列的长度 +1 的最大值
      • if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
    • 初始化:全1
    • 遍历顺序:外层从左到右(dp[i]依赖于其左边的元素)内层从0到 i - 1或从 i - 1到0都可以
  • 代码:
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if (nums.size() <= 1) return nums.size();
        vector<int> dp(nums.size(), 1);
        int result = 0;
        for (int i = 1; i < nums.size(); ++i) {
            for (int j = 0; j < i; ++j) {
                if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
            }
            if (dp[i] > result) result = dp[i]; // 取长的子序列
        }
        return result;
    }
};

LeetCode 674. 最长连续递增序列

给定一个未经排序的整数数组,返回其中最长连续递增子序列的长度。

视频讲解https://www.bilibili.com/video/BV1bD4y1778v文章讲解https://programmercarl.com/0674.%E6%9C%80%E9%95%BF%E8%BF%9E%E7%BB%AD%E9%80%92%E5%A2%9E%E5%BA%8F%E5%88%97.html

  • 思路:
    • dp数组含义:dp[i]表示数组下标[0, i]中,以nums[i]结尾的最长递增子序列的长度
    • 递推公式:
      • 连续:只需要比较 nums[i] 和 nums[i - 1]
      • nums[i] > nums[i - 1]👉dp[i] = dp[i - 1] + 1;(连上了,+1)
      • 否则有dp[i] = 1;(没连上,从i位置重新开始)
    • 初始化:全1
    • 遍历顺序:从左到右
  • 代码:
// 动规解法:
class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        int result = 1;
        vector<int> dp(nums.size() ,1);
        for (int i = 1; i < nums.size(); ++i) {
            if (nums[i] > nums[i - 1]) { // 连续记录
                dp[i] = dp[i - 1] + 1;
            }
            if (dp[i] > result) result = dp[i];
        }
        return result;
    }
};
// 时间复杂度:O(n)
// 空间复杂度:O(n)
// 贪心解法:遇到nums[i] > nums[i - 1]的情况,count就++,否则count为1,返回count的最大值
class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        int result = 1; // 连续子序列最少也是1
        int count = 1;
        for (int i = 1; i < nums.size(); ++i) {
            if (nums[i] > nums[i - 1]) { // 连续记录
                count++;
            } else { // 不连续,count从头开始
                count = 1;
            }
            if (count > result) result = count;
        }
        return result;
    }
};
// 时间复杂度:O(n)
// 空间复杂度:O(1)

LeetCode 718. 最长重复子数组

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

注:子序列 vs 子数组(连续子序列

视频讲解https://www.bilibili.com/video/BV178411H7hV文章讲解https://programmercarl.com/0718.%E6%9C%80%E9%95%BF%E9%87%8D%E5%A4%8D%E5%AD%90%E6%95%B0%E7%BB%84.html

  • 思路:
    • dp数组含义:
      • dp[i][j]:以 nums1[i - 1] 结尾、以 nums2[j - 1] 结尾的最长重复子数组的长度
      • 注:如果定义成以 nums1[i] 结尾、以 nums2[j] 结尾dp[i][0] 和 dp[0][j]就有意义了,需要分别遍历 i 和 j 来初始化
    • 递推公式:
      • nums1[i - 1]nums2[j - 1] 相等时,dp[i][j] = dp[i - 1][j - 1] + 1;
    • 初始化:
      • 根据dp[i][j]的定义,dp[i][0] 和 dp[0][j] 都是没有意义的,初值符合递推公式即可
      • 考虑:dp[i][1]👉比较 nums1[i - 1] 和 nums2[0]👉若相等则 dp[i][1] 为1
      • 全部初始化为0
    • 遍历顺序:
      • 外层遍历 nums1、内层遍历 nums2,或者反过来都可以(两数组之间无顺序要求)
      • 外层下标从小到大遍历(因为 dp[i][j] 依赖于 dp[i - 1][j - 1])

  • 代码:
// 版本一
class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        vector<vector<int>> dp (nums1.size() + 1, vector<int>(nums2.size() + 1, 0));
        int result = 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;
                }
                if (dp[i][j] > result) result = dp[i][j];
            }
        }
        return result;
    }
};
// 时间复杂度:O(n × m),n为nums1长度,m为nums2长度
// 空间复杂度:O(n × m)
// 版本二:滚动数组,内层循环一定要从后往前遍历
class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        vector<int> dp(vector<int>(B.size() + 1, 0));
        int result = 0;
        for (int i = 1; i <= A.size(); i++) {
            for (int j = B.size(); j > 0; j--) {
                if (A[i - 1] == B[j - 1]) {
                    dp[j] = dp[j - 1] + 1;
                } else dp[j] = 0; // 注意这里不相等的时候要有赋0的操作
                if (dp[j] > result) result = dp[j];
            }
        }
        return result;
    }
};
// 时间复杂度:O(n × m),n为A长度,m为B长度
// 空间复杂度:O(m)

总结:子序列 / 子数组问题

  • dp数组含义:
    • dp[i] 表示 以nums[i]结尾的最长...长度
    • 如果涉及两个数组nums1、nums2👉dp[i][j] 表示 以nums1[?]结尾、以nums2[?]结尾...
  • 递推公式:
    • 搞清楚前一个状态是什么
    • 根据题意,确定当前状态是 直接赋值 还是 取max / min
  • 初始化:如果[0]无意义,通过递推公式倒推一个合法值
  • 遍历顺序:外层/内层可否交换?每一层如何遍历?(从递推公式入手,看状态间依赖关系)
  • 返回结果:有别于打家劫舍、股票问题,可能出现在任意下标,计算dp数组时顺便记录 result

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

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

相关文章

蓝库云|一文搞懂什么是MES(制造执行系统),制造业该如何选择

MES&#xff08;Manufacturing Execution System&#xff09;是一种将制造过程可视化并为工人提供指导和支持的系统。它的优势在于可以优化人员、机器和设备等资源&#xff0c;消除制造对个人技能的依赖。在本文中&#xff0c;蓝库云将以通俗易懂的方式说明MES的概要以及与生产…

CS5260电路参考|Type-C转VGA转换器方案|Type-C转VGA转接线方案

CS5260电路参考|Type-C转VGA转换器方案|Type-C转VGA转接线方案 CS5260是一款TYPEC转VGA转换方案芯片。 CS5260作为标准的USB Type-C显示端口Alt模式接收器&#xff0c;CS5260由双通道主链路差分对&#xff0c;一个AUX通道差分对组成。 CS5260主链接作为双通道差分对&#x…

npm Eslint 报错

❤ npm Eslint 报错 npm init --yes初始化项目 ○ 安装ESLint模块 npm add eslint --dev&#xff0c;node-modules/.bin目录生成eslint的cli程序 ○ 查看eslint的版本 使用npm eslint --version ○ 使用yarn eslint ./index.js 当代码中出现语法错误时&#xff0c;eslint无法检…

vue前端框架应用案例(一)实现简单的加法页面

目录vue实现效果目录结构Count.vueApp.vuemain.jsindex.htmlvuex实现效果vuex使用步骤vuex基本结构目录结构store/index.js文件CountVuex.vueApp.vuemain.jsindex.html本博客参考尚硅谷官方课程&#xff0c;详细请参考 【尚硅谷bilibili官方】 本博客以vue2作为学习目标&…

【黄啊码】windows如何使用tp5.1配置workerman和gateway(不要看官方文档,不要抄网友文档,OK?)

大家好&#xff0c;我是黄啊码&#xff0c;由于项目需要被迫无奈在老项目上整合workerman&#xff0c;整整浪费了我一天&#xff0c;按着tp官方文档去做&#xff0c;一个又一个的坑&#xff0c;然后百度网友的答案&#xff0c;又是一个又一个的天坑&#xff0c;真的无力吐槽&am…

基于Android 的校园疫情防控管理系统设计与实现

需求信息&#xff1a; (1〉通知公告。各级联络员可在此发布各类通知公告。 (2〉应急动态。发布国家公布的各类数据信息&#xff0c;如在本次疫情期间&#xff0c;平台集成丁香园丁香医生疫情动态模板&#xff0c;实时更新全国疫情数据&#xff0c;帮助师生了解疫情地图&#xf…

建设工程质量检测管理办法3月1日起施行

建设工程质量检测管理办法&#xff08;2022年12月29日中华人民共和国住房和城乡建设部令第57号公布 自2023年3月1日起施行&#xff09;第一章 总则第一条 为了加强对建设工程质量检测的管理&#xff0c;根据《中华人民共和国建筑法》《建设工程质量管理条例》《建设工程抗震…

液晶12864显示字符

液晶12864简介12864是128*64点阵液晶模块的点阵数简称。基本参数1、低电源电压&#xff08;VDD:3.0&#xff5e;5.5V&#xff09;。2、显示分辨率:12864点。3、内置汉字字库&#xff0c;提供8192个1616点阵汉字。4、内置128 个168 点阵字符。5、2MHZ 时钟频率。6、显示方式&…

PriorityQueue

PriorityQueue其本质是一个优先级队列的集合。 1. 优先级队列 那什么是优先级队列呢&#xff1f;我们先从它的概念聊起。 概念&#xff1a; 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&a…

Grafana 中文入门教程 | 构建你的第一个仪表盘

Grafana 读音&#xff1a;/grəˈfɑːnˌɑː/ 在大厂工作久了&#xff0c;时常对一些工具的存在觉得理所当然。 比如说&#xff0c;需要计算资源的时候&#xff0c;一个配置文件就可以要来两百台虚拟化好的机子。需要试下缓存&#xff1f;点下鼠标就可以要到几十个配置好的…

简单高效的字符串匹配算法

Quick Search算法 算法简介 Quick Search算法属于Sunday算法的一种。Sunday算法由Daniel M Sunday在1990年提出。论文原文&#xff1a;A VERV FAST SU6STRINC SEARCH ALGORITHM 在论文中&#xff0c;作者提出了三个不同的算法&#xff1a;Quick Search算法、Maximal Shift算…

IO流——字符缓冲流

复制文本文件–一次读写一个字符 –一次读写一个字符数组 不带参数&#xff1a; package com.demo03;import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;/** 需求&#xff1a;* 把项目路径下的FileWriterDemo.java中的内容复制到项目路径…

上门服务小程序怎么开发-上门服务小程序源码功能

目前上门服务类型新型行业已经占据了很大的市场所在&#xff0c;上门家政服务&#xff0c;上门做饭&#xff0c;上门按摩&#xff0c;上门私教&#xff0c;上门美容没发等等一些列的&#xff0c;目前上门系列的在市场分额还是特别大的&#xff0c;趋势比较大&#xff0c;今天就…

Docker 安装镜像与使用命令

按照阿里云的操作文档安装 docker&#xff1a;https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 这里仅写 Windows 版的&#xff0c;其他版本见上面的链接 1. 安装&#xff0f;升级Docker客户端 对于Windows 10以下的用户&#xff0c;推荐使用Docker ToolboxWin…

一文带你了解UI自动化测试框架

PythonSeleniumUnittestDdtHTMLReport分布式数据驱动自动化测试框架结构 1、Business&#xff1a;公共业务模块&#xff0c;如登录模块&#xff0c;可以把登录模块进行封装供调用 ------login_business.py from Page_Object.Common_Page.login_page import Login_Page from H…

九龙证券|首月定增市场“开门红” 上市公司密集融资谋扩产

2023年首月&#xff0c;A股定增市场迎来“开门红”。 据上海证券报记者统计&#xff0c;年初至今&#xff0c;已有35家公司完成定增&#xff0c;合计募资986.86亿元&#xff0c;较上年同期的477.3亿元大幅增长超100%&#xff0c;延续了2022年末的高位运行态势。同时&#xff0c…

前端项目发布后,如何使正在使用的用户更新为最新的版本?

1.背景 每次项目上线后&#xff0c;异常监控总是零零散散报一些资源加载或者解析失败的告警 仔细对比chunk的hash值会发现已经是上一版本的js文件为什么会出现这个问题呢&#xff1f;也不难想到&#xff0c;项目是单页应用&#xff0c;页面使用懒加载分多个chunk打包&#xff…

SDP零信任网络安全架构

安全狗零信任SDP接入解决方案基于“以身份认证为中心&#xff0c;以信任为基础&#xff0c;持续动态授权认证”的理念&#xff0c;打造企业全方位立体业务访问安全体系。 其SDP零信任网络安全架构如下图&#xff1a; SDP零信任产品优势 1、多维度终端环境感知 系统风险感知&…

浅谈--声调

声调 根据声调的有无&#xff0c;我们可以把世界上的语言分为声调语言和非声调语言两大类。 非声调语言&#xff0c;并不是说音节没有高低升降的音高变化&#xff0c;只是这种变化只能改变语气作用&#xff0c;并不能区别意义。如&#xff1a;在英语单词book&#xff0c;音高…

Nacos 初始

1.Nacos 的安装使用。 nacos的安装步骤 1.端口配置 Nacos的默认端口是8848&#xff0c;如果你电脑上的其它进程占用了8848端口&#xff0c;请先尝试关闭该进程。 如果无法关闭占用8848端口的进程&#xff0c;也可以进入nacos的conf目录&#xff0c;修改配置文件中的端口&am…