力扣718-最长重复子数组(Java详细题解)

news2024/11/13 9:53:56

题目链接:718. 最长重复子数组 - 力扣(LeetCode)

前情提要:

因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。

dp五部曲。

1.确定dp数组和i下标的含义。

2.确定递推公式。

3.dp初始化。

4.确定dp的遍历顺序。

5.如果没有ac打印dp数组 利于debug。

每一个dp题目如果都用这五步分析清楚,那么这道题就能解出来了。

题目思路:

如果没有接触过子序列问题,那么第一次做这个题还是很有难度。

本题要求俩个数组中的公共最长连续子序列。

注意这里是要求连续的。

那么如果你做过674. 最长连续递增序列 - 力扣(LeetCode)或者看了我的题解力扣674-最长连续递增序列(Java详细题解)-CSDN博客,那么会好理解这道题一点。

话不多说,直接开始我们的dp五部曲。

1.确定dp数组和i下标的含义。

该题是要求俩个数组公共的子数组长度,那我们就要比较俩个数组的任意俩个元素。那我们是不是要用二维的dp数组来记录下这个状态呀。

用二维dp数组来记录每一个数组元素和另一个数组元素相比较的结果。

所以就要用到dp[i] [j]了。

注意这里dp[i] [j]的含义是指以i - 1结尾的数组和j - 1为结尾的数组俩个数组的最长公共子序列。

这里的dp含义在下面很多篇都会用到,大家要牢记这点。

至于为什么要设置i - 1和j - 1这样的含义,我们在初始化那个环节会讲,这里大家记住这个定义就好。

2.确定递推公式。

因为是要求公共的子数组,所以可能是当nums[i - 1] == nums[j - 1]的时候加入我们的结果。

为什么是i - 1和j - 1?

因为dp数组定义的就是i - 1结尾的数组和j - 1为结尾的数组俩个数组的最长公共子序列,所以只有nums[i - 1] == nums[j - 1]时,他们的dp[i] [j]才能被推出。

dp[i] [j] = 什么呢?

当nums[i - 1] == nums[j - 1]的时候,dp[i] [j] = dp[i - 1] [j - 1] + 1。

因为是求连续的公共数组,所以dp[i] [j] 只与他们前面一个状态dp[i - 1] [j - 1]有关。

当nums[i - 1] == nums[j - 1],dp[i] [j]是由dp[i - 1] [j - 1](下标i - 2结尾的数组和j - 2为结尾的数组俩个数组的最长公共子序列长度)加上 nums[i - 1] nums[j - 1]这俩个元素相同的长度,也就是1。

所以dp[i] [j] = dp[i - 1] [j - 1] + 1。

3.dp初始化。

该题的初始化部分很重要。

由递推公式可以看出,每一个dp[i] [j]在二维数组中都是由它左上的位置得出,所以要初始化dp[i] [0]和dp[0] [i]。也就是第一排和第一列。

由于dp数组定义的是以i - 1结尾的数组和j - 1为结尾的数组俩个数组的最长公共子序列。

所以第一排(dp[0] [i])是以下标-1为结尾的数组和i - 1为结尾的数组俩个数组的最长公共子序列。

以下标-1为结尾的数组不存在,所以他们的最长公共子序列自然就为0。

第一列同理可以得出也都初始化为0。

这就是我们为什么将dp数组定义为以i - 1和j - 1为结尾的数组的最长公共子序列。

这样便于初始化。如果定义为以i和j为结尾的数组最长公共子序列。

那么第一排第一列初始化就不一样了。

他们第一排和第一列是有意义的,并且他们还可能相同。

所以要遍历一遍第一列和第一排,如果nums[i] == nums[j] 那么dp[i] [j] = 1。

因为他们的值相同,第一排和第一列的最长公共子序列就为该元素。

4.确定dp的遍历顺序。

由递推公式可以看出dp[i] [j] 由dp[i - 1] [j - 1]可得。所以要从左到右,从上到下去遍历。

5.如果没有ac打印dp数组 利于debug。

在这里插入图片描述

最终代码:

class Solution {
    public int findLength(int[] nums1, int[] nums2) {
        //这里的dp含义是 以i - 1和j - 1为结尾的俩个数组最长子数组的长度。
        //为什么 定义 i- 1和 j - 1呢 是为了初始化方便。
        //递推公式 当nums1[i - 1] == nums2[j - 1] 说明俩个数组出现相等的值了 既然出现相等的值了
        //那我的dp[i][j] 就要加1了 因为我dp[i][j]是记录的i - 1和j - 1为结尾的俩个数组最长子数组的长度
        //那么在哪个状态上家呢?
        //其实子数组就是一种连续子序列 他的状态只与他的前一状态有关  所以与dp[i - 1][j - 1]有关
        //那么dp[i][j] = dp[i - 1][j - 1] + 1
        //紧接着我们就要进行初始化了
        //
        int [][] dp = new int [nums1.length + 1][nums2.length + 1];
        int result = 0;
        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;
                }
                //因为只有nums1[i - 1] == nums2[j - 1]才会进入我们的dp数组,所以任意位置的dp数组都可能是最大的,所以我们要遍历一遍求最大的。
                result = Math.max(result,dp[i][j]);
            }
        }
        return result;
    }
}

这一篇博客就到这了,如果你有什么疑问和想法可以打在评论区,或者私信我。

我很乐意为你解答。那么我们下篇再见!

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

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

相关文章

【CMake】使用CMake在Visual Studio内构建多文件夹工程

一、配置准备 打开VIsual Studio&#xff0c;载入写好的 C M a k e l i s t s . t x t CMakelists.txt CMakelists.txt&#xff0c;在项目中添加以下文件&#xff1a; 创建一个文件夹 f u n c s funcs funcs&#xff0c;里面放入 f u n c . h func.h func.h、 f u n c . c p …

fmql之驱动程序编写(首次)

看了正点原子的zynq系列的Linux开发指南&#xff08;pdf和视频均有&#xff09;&#xff0c;因此从最简单的程序开始。 驱动程序开发&#xff1a;&#xff08;第四期视频&#xff09; 第3.1讲 我的第一个Linux驱动-字符设备驱动框架_哔哩哔哩_bilibili 学习驱动程序编写之前&am…

【论文串烧】多媒体推荐中的模态平衡学习 | 音视频语音识别中丢失导致的模态偏差对丢失视频帧鲁棒性的影响

文章目录 一、多媒体推荐中的模态平衡学习1.1 研究背景1.2 解决问题1.3 实施方案1.4 文章摘要1.5 文章重点1.6 文章图示图 1&#xff1a;不同模型变体在 AmazonClothing 数据集上的初步研究图 2&#xff1a;CKD模型架构的说明图 3&#xff1a;在 Amazon-Clothing 数据集上训练过…

【Linux:共享内存】

共享内存的概念&#xff1a; 操作系统通过页表将共享内存的起始虚拟地址映射到当前进程的地址空间中共享内存是由需要通信的双方进程之一来创建但该资源并不属于创建它的进程&#xff0c;而属于操作系统 共享内存可以在系统中存在多份&#xff0c;供不同个数&#xff0c;不同进…

Qt窗口——QStatusBar

文章目录 状态栏状态栏创建状态栏显示临时消息状态栏添加子控件 状态栏 QStatusBar状态栏是应用程序中输出简要信息的区域&#xff0c;例如画图板下面的区域 我们也可以给程序设置状态栏&#xff0c;表示一些状态。 状态栏创建 使用Qt Creator创建项目的时候&#xff0c;如果…

实现一种可插拔的参数校验

1、概述 仿照mybatis的二级缓存的实现方式&#xff0c;使用“策略模式配置” 的方式实现一个可动态插拔的 参数校验&#xff0c;便于后期扩展。 实现方式也很简单&#xff0c;首先定义一个校验接口&#xff0c;并提供一个校验方法&#xff1b;每种参数校验都是实现 了该校验接口…

前端vue-实现富文本组件

1.使用wangeditor富文本编辑器 工具网站&#xff1a;https://www.wangeditor.com/v4/ 下载安装命令&#xff1a;npm i wangeditor --save 成品如下图&#xff1a; 组件实现代码 <template><div><!-- 富文本编辑器 --><div id"wangeditor">…

Recbole安装指南:步骤详解与常见问题解决方案

1.两种方式&#xff1a; 从Conda安装 如果你还没有安装Conda&#xff0c;可以安装Miniconda或完整的Anaconda。 如果你在中国大陆&#xff0c;我们推荐你使用清华镜像安装Conda。 当你完成Conda的安装后&#xff0c;你可以将RecBole安装在python 3.7的Conda环境中&#xff0…

数据结构之树(下),你真的懂吗?

数据结构入门学习&#xff08;全是干货&#xff09;——树&#xff08;下&#xff09; 1 堆 (Heap) 1.1 什么是堆 堆 (Heap) 是一种特殊的完全二叉树&#xff0c;分为最大堆和最小堆。 最大堆&#xff1a;每个节点的值都大于或等于其子节点的值&#xff0c;根节点是整个堆的…

YOLOv9改进策略【注意力机制篇】| MCAttention 多尺度交叉轴注意力

一、本文介绍 本文记录的是基于MCA注意力模块的YOLOv9目标检测改进方法研究。普通的轴向注意力难以实现长距离交互&#xff0c;不利于捕获分割任务中所需的空间结构或形状&#xff0c;而MCA注意力模块通过构建了两个并行轴向注意力之间的交互&#xff0c;更有效地利用多尺度特…

2.4 卷积2

2.4.2 复正弦波与整体方案 在2.3节中&#xff0c;我们提出了关于复正弦输入的频域输出及其意义的两个问题。为了研究这些问题&#xff0c;我们让一个具有真实脉冲响应 h [ n ] h[n] h[n]&#xff08;即 h Q [ n ] 0 h_Q[n] 0 hQ​[n]0&#xff09;的LTI系统通过输入复正弦…

数据结构(Day16)

一、学习内容 1、有关顺序表的操作&#xff08;功能函数&#xff09; 1、创建顺序表 Plist create_list(){Plist L malloc(sizeof(list)); // 为顺序表分配内存空间if(NULL L){printf("申请空间失败\n");return NULL; // 如果内存分配失败&#xff0c;返回 NU…

RTMP协议在无人机巡检中的应用场景

为什么要用无人机巡检 好多开发者对无人机巡检技术方案&#xff0c;相对陌生&#xff0c;实际上&#xff0c;无人机巡检就是利用无人机对特定区域或设施进行定期或不定期的检查。这种巡检方式相比传统的人工巡检具有显著的优势&#xff0c;包括速度快、覆盖广、风险低、准确性…

Tornado 是一个 Python 异步网络库和 web 框架

Tornado 是一个 Python 异步网络库和 web 框架&#xff0c;它最初由 FriendFeed 开发&#xff0c;后来被 Facebook 收购并开源。Tornado 因其非阻塞的 I/O 操作和优秀的性能而广受欢迎&#xff0c;特别是在需要处理大量并发连接的应用中。Tornado 的底层实现主要依赖于 Python …

神经网络通俗理解学习笔记(0) numpy、matplotlib

Numpy numpynumpy 基本介绍Ndarray对象及其创建Numpy数组的基础索引numpy数组的合并与拆分&#xff08;重要&#xff09;numpy数组的矩阵运算Numpy数组的统计运算numpy中的arg运算numpy中的神奇索引和比较 Matplotlib numpy numpy 基本介绍 numpy 大多数机器学习库都用了这个…

【Linux入门】基本指令(一)

目录 一.使用环境 二.快捷键 三. 登录与用户管理 1.ssh root[ip地址] 2.whoami 3.ls /home 4.adduser [用户名] 5.passwd [用户名] 四.目录文件操作 1.ls 2.pwd 3.cd 4.touch 5.mkdir 6.rm 7.cp 五.命令手册 一.使用环境 云服务器&#xff1a;市面上有很多&am…

Python 中的 typing 模块常见用法

typing 模块是 Python 提供的一个标准库&#xff0c;主要用于为函数、变量和类定义类型提示&#xff08;Type Hints&#xff09;&#xff0c;从而提高代码的可读性和类型安全性。虽然 Python 是动态类型语言&#xff0c;但通过 typing 模块&#xff0c;开发者可以明确指定变量和…

TMStarget学习——Functional Connectivity

今天基于结构像和功能像数据试验操作TMStarget 的第二个功能模块Functional Connectivity。参考季老师的文档PPT来学习的&#xff0c;整个处理过程蛮长的&#xff0c;可能配置原因一路上报错也比较多&#xff0c;下面还是逐步记录吧&#xff0c;后面采用连更的方式直到跑通后再…

C++ 中的继承(详细讲解)

一、继承的概念以及定义 1、继承概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象 程序设计的…

微波无源器件 功分器 4 一种用于天线阵列的紧凑宽带四路双极化波导功分器

摘要&#xff1a; 一种新型紧凑和高效率&#xff0c;在一个同相2x4方案(四路)显示双极化的功分器的设计和仿真被提出了&#xff0c;两个基本的正交模式TE10和TE01在四个方波导处同相输出通过使用四个3端口个四个E面和两个H面功分结构。此功分末端接了两个商用波导(WR75)端口&am…