代码随想录-刷题第五十二天

news2025/1/18 9:11:22

300. 最长递增子序列

题目链接:300. 最长递增子序列

思路:动态规划五步曲:

  1. dp[i]表示从0到i,以nums[i]结尾的最长递增子序列的长度。

  2. 递推公式:if(nums[i]>nums[j]) dp[i] = max(dp[i], dp[j] + 1)

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

    注意这里不是 dp[i] 与 dp[j] + 1 进行比较,而是要取 dp[j] + 1 的最大值

  3. 初始化:dp[i]都初始化为1

    每一个i,对应的dp[i](即最长递增子序列)起始大小至少都是1。

  4. 遍历顺序:从递推公式可以看出需要从前向后遍历。

    dp[i] 是有 0 到 i-1 各个位置的最长递增子序列推导而来,那么遍历i一定是从前向后遍历

    j其实就是遍历 0 到 i-1,那么是从前到后,还是从后到前遍历都无所谓,只要把 0 到 i-1 的元素都遍历了就行,所以默认习惯从前向后遍历。

  5. 举例推导dp数组

    输入:[0,1,0,3,2],dp数组的变化如下:

    300.最长上升子序列

    如果代码写出来,但一直AC不了,那么就把dp数组打印出来,看看对不对!

class Solution {
    public int lengthOfLIS(int[] nums) {
        // dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列的长度
        int[] dp = new int[nums.length];
        // dp 数组全都初始化为 1
        Arrays.fill(dp, 1);
        int res = 1;

        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
                if (dp[i] > res) res = dp[i]; // 取长的子序列
            }
        }
        
        return res;
    }
}

674. 最长连续递增序列

题目链接:674. 最长连续递增序列

思路:本题相对于上一题来说多了一个连续的条件,动态规划五步曲:

  1. dp[i] 表示从0到i,以nums[i]为结尾的最长连续递增子序列长度。

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

  2. 递推公式:if(nums[i] > nums[i - 1]) dp[i] = dp[i - 1] + 1

    如果 nums[i] > nums[i - 1],那么以 i 为结尾的连续递增的子序列长度 一定等于 以i - 1为结尾的连续递增的子序列长度 + 1 。

    因为本题要求连续递增子序列,所以就只要比较nums[i]与nums[i - 1],而不用去比较nums[j]与nums[i] (j是在0到i之间遍历)。

    既然不用j了,那么也不用两层for循环,一层for循环就行,比较nums[i] 和 nums[i - 1]。

  3. 初始化:dp[i]都初始化为1

    以下标i为结尾的连续递增的子序列长度最少也应该是1,即就是nums[i]这一个元素。

  4. 遍历顺序:从递推公式可以看出需要从前向后遍历。

  5. 举例推导dp数组

    以输入nums = [1,3,5,4,7]为例,dp数组状态如下:

    674.最长连续递增序列

    注意这里要取dp[i]里的最大值,所以dp[2]才是结果!

class Solution {
    public int findLengthOfLCIS(int[] nums) {
        // dp[i] 表示以nums[i]为结尾的最长连续递增子序列长度
        int[] dp = new int[nums.length];
        // dp 数组全都初始化为 1
        Arrays.fill(dp, 1);
        int res = 1;
        
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > nums[i - 1]) {
                dp[i] = dp[i - 1] + 1;
            }
            if (dp[i] > res) res = dp[i]; // 取长的连续递增子序列
        }
        return res;
    }
}

这道题目也可以用贪心来解决

class Solution {
    public static int findLengthOfLCIS(int[] nums) {
        int res = 1; // 连续子序列最少也是1
        int count = 1;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > nums[i - 1]) { // 连续记录
                count++;
            } else { // 不连续,count从头开始
                count = 1;
            }
            if (count > res) res = count;
        }
        return res;
    }
}

718. 最长重复子数组

题目链接:718. 最长重复子数组

思路:注意题目中说的子数组,其实就是连续子序列。动态规划五步曲:

  1. dp[i][j] :以下标i - 1为结尾的A和以下标j - 1为结尾的B,最长重复子数组的长度为dp[i][j]

    特别注意:“以下标i - 1为结尾的A” 表明一定是以A[i - 1]为结尾的子数组。

    dp[0][0]是什么含义呢?总不能是以下标-1为结尾的A数组吧。

    其实dp[i][j]的定义也就决定着,在遍历dp[i][j]的时候i 和 j都要从1开始。

  2. 递推公式:if(nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1

    根据dp[i][j]的定义,dp[i][j]的状态只能由dp[i - 1][j - 1]推导出来

    即当A[i - 1]和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1

  3. 初始化:dp[i][0]和dp[0][j]初始化为0。

    根据dp[i][j]的定义,dp[i][0] 和dp[0][j]其实都是没有意义的!

    但dp[i][0] 和dp[0][j]要初始值,为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1,所以dp[i][0]和dp[0][j]初始化为0。

  4. 遍历顺序:需要从前向后遍历,先遍历i或者j都可以。

  5. 举例推导dp数组

    以A: [1,2,3,2,1],B: [3,2,1,4,7]为例,画一个dp数组的状态变化,如下:

    718.最长重复子数组

class Solution {
    public int findLength(int[] nums1, int[] nums2) {
        int m = nums1.length, n = nums2.length;
        int res = 0;
        int[][] dp = new int[m + 1][n + 1];
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (nums1[i - 1] == nums2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }
                if (dp[i][j] > res) res = dp[i][j];
            }
        }
        
        return res;
    }
}

题目要求长度最长的子数组的长度,所以在遍历的时候顺便把dp[i][j]的最大值记录下来。


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

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

相关文章

Spring cloud聚合父工程project

文章目录 本次微服务版本一. 新建父工程project1.1设置字符集utf-81.2注解生效激活1.3. Java8编译版本 二. 父工程 pom.xml 本次微服务版本 一. 新建父工程project 1.1设置字符集utf-8 1.2注解生效激活 1.3. Java8编译版本 二. 父工程 pom.xml <?xml version"1.0&quo…

HTTP 3xx状态码:重定向的场景与区别

HTTP 状态码是服务器响应请求时传递给客户端的重要信息。3xx 系列的状态码主要与重定向有关&#xff0c;用于指示请求的资源已被移动到不同的位置&#xff0c;需要采取不同的操作来访问。 一、301 Moved Permanently 定义&#xff1a; 服务器表明请求的资源已永久移动到一个新…

Python多线程同步

同步条件(Event) 在Python中&#xff0c;多线程同步可以通过threading模块中的Event对象来实现。Event对象允许一个或多个线程等待某个事件的发生&#xff0c;当事件发生时&#xff0c;等待的线程将被唤醒。 event.isSet()&#xff1a;返回event的状态值 event.wait()&#x…

Vue-11、Vue计算属性

Vue计算属性是Vue实例的属性&#xff0c;用来根据已有的数据进行计算得到新的数据。计算属性的值会根据它的依赖缓存起来&#xff0c;在依赖没有发生改变时直接返回缓存的值&#xff0c;提高了性能。 计算属性的定义方式为在Vue实例中使用computed关键字&#xff0c;并将计算属…

Pycharm中如何配置python环境(conda)

首先在pycharm中点击 "File" > "Settings" 再次点击如下操作&#xff1a; 点击Python Interpreter的最右侧按钮&#xff0c;点击Show All... 找到python文件 最后点击OK

YOLOv8改进 | 主干篇 | 12月最新成果UniRepLknet特征提取网络(附对比试验效果图)

一、本文介绍 本文给大家带来的改进机制是特征提取网络UniRepLknet,其也是发表于今年12月份的最新特征提取网络,该网络结构的重点在于使用Dilated Reparam Block和大核心指导原则,强调了高效的结构进行通道间通讯和空间聚合,以及使用带扩张的小核心进行重新参数化,该网络…

实现LCM在docker之间的通信

目录 1.docker容器互联 新建网络 连接容器 2.设置环境变量 3.在两个docker之间实现通信 1.docker容器互联 新建网络 $ docker network create -d bridge test-net 连接容器 运行一个容器并连接到新建的 test-net 网络: $ docker run -itd --name lcm_1 --network tes…

Postman工具初学一篇快速入门教程

文章目录 下载安装注册登录CollectionFolderRequestGet请求Post请求Header设置Response响应 EnvironmentsGlobal环境变量其他环境变量Collection变量变量使用同名变量的优先级 Postman内置变量Pre-request script和Test script脚本设置、删除和获取变量获取请求参数获取响应数据…

无失真编码之算术编码的python实现——数字图像处理

原理 无失真编码中的算术编码是一种用于将输入数据进行高效压缩的方法&#xff0c;同时保留了原始数据的完整性。 算术编码的实现过程如下&#xff1a; 数据分段&#xff1a;首先&#xff0c;将要进行编码的数据划分为一个个符号或字符。每个符号可以是文本中的一个字母、一幅…

数学建模-Matlab R2022a安装步骤

软件介绍 MATLAB是一款商业数学软件&#xff0c;用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境&#xff0c;主要包括MATLAB和Simulink两大部分&#xff0c;可以进行矩阵运算、绘制函数和数据、实现算法、创建用户界面、连接其他编程语言的程…

jenkins构建git项目timeout

问题点&#xff1a; Started by user unknown or anonymous Running as SYSTEM Building in workspace /var/jenkins_home/workspace/test-one using credential f28d956-8ee1-4f20-a32b-06879b487c70 Cloning the remote Git repository Cloning repository http://git.cc.co…

[足式机器人]Part2 Dr. CAN学习笔记 - Ch02动态系统建模与分析

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - Ch02动态系统建模与分析 1. 课程介绍2. 电路系统建模、基尔霍夫定律3. 流体系统建模4. 拉普拉斯变换&#xff08;Laplace&#xff09;传递函数、微分方程4.1 Laplace Transform 拉式变换4.2 收…

关于进制在输出时的转换【C语言】

目录 输入输出格式参考文章 1. 十进制整数作为八进制/十六进制输出 2. 八进制整数作为十进制/十六进制输出 3. 十六进制整数作为八进制/十进制输出 我们处理的整数通常用十进制表示&#xff0c;在计算机内存中是以二进制补码形式存储&#xff0c;但通常二进制表示的整数比较…

C#封装服务

C#封装服务 新建服务项目&#xff1b;重构 OnStart 和 OnStop using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using S…

基础数据结构第十期 哈希表(数组+STL)

前言&#xff1a; 哈希表是一种非常重要的数据结构&#xff0c;希望大家都能够熟练掌握&#xff01;&#xff01;&#xff01; 一、哈希表的基本内容 哈希表&#xff08;Hash Table&#xff09;&#xff0c;也被称为哈希映射&#xff08;Hash Map&#xff09;或字典&#xf…

Redis底层原理

持久化 Redis虽然是个内存数据库,但是Redis支持RDB和AOF两种持久化机制,将数据写往磁盘,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复。 RDB RDB持久化是把当前进程数据生成快照保存到硬盘的过程。所谓内存快照,就是…

vue2使用文件上传读取本地照片并转化base64格式进行展示

创建个vue2项目,直接把代码放到一个vue2页面内运行就好,下面代码拿来即用 <template><div><div class"replace_menu_mask" click"closeMenu"><img :src"replaceImg" alt"" style"width: 100%;">&l…

企业微信forMAC,如何左右翻动预览图片

1、control commandshifd 进入企业微信的debug调试模式 2、按照如下步骤选择 3、重启企业微信

【漏洞复现】锐捷EG易网关login.php命令注入漏洞

Nx01 产品简介 锐捷EG易网关是一款综合网关&#xff0c;由锐捷网络完全自主研发。它集成了先进的软硬件体系架构&#xff0c;配备了DPI深入分析引擎、行为分析/管理引擎&#xff0c;可以在保证网络出口高效转发的条件下&#xff0c;提供专业的流控功能、出色的URL过滤以及本地化…

【复习】人工智能 第7章 专家系统与机器学习

专家系统就是让机器人当某个领域的专家&#xff0c;但这章专家系统不咋考&#xff0c;主要靠书上没有的机器学习。 一、专家系统的基本组成 二、专家系统与传统程序的比较 &#xff08;1&#xff09;编程思想&#xff1a; 传统程序 数据结构 算法 专家系统 知识 推理 &…