当前位置: 首页> 娱乐> 影视 > 建筑工程网登_鲜花商城网站模板_成都外贸seo_惠州seo代理

建筑工程网登_鲜花商城网站模板_成都外贸seo_惠州seo代理

时间:2025/7/15 5:55:11来源:https://blog.csdn.net/2302_79761426/article/details/142354894 浏览次数:0次
建筑工程网登_鲜花商城网站模板_成都外贸seo_惠州seo代理

题目链接: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;}
}

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

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

关键字:建筑工程网登_鲜花商城网站模板_成都外贸seo_惠州seo代理

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: