代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组

简介: 代码随想录 Day44 动规12 LeetCode T300 最长递增子序列 T674 最长连续递增序列 T718 最长重复子数组

前言

本期我们来解决动规的经典题型------  子数组问题

我们还是会使用动规五部曲来解决问题,下面我们仍然列出动规五部曲

1.明确dp数组含义

2.明确dp数组如何推导-递推公式

3.初始化dp数组

4.确定遍历顺序

5.打印dp数组排错

LeetCode T300 最长递增子序列

题目链接:300. 最长递增子序列 - 力扣(LeetCode)

题目思路:

1.明确dp数组含义

这里的dp[i]表示的是以dp[i]为结尾的最长递增子序列的长度

2.明确dp数组如何推导-递推公式

我们知道这里的递增不要求连续,只需要位置在i前面即可,所以我们定义一个j来遍历i前面的元素,这里dp[i]就等于dp[j]+1或者本身或者是dp[j]+1之间的最大值,因为在这个期间我们可以不断的更新dp[i]

3.初始化dp数组

初始化全为1即可

由于单个字母也构成递增子序列,所以长度为1

4.确定遍历顺序

顺序遍历,因为后面的dp值是由前面的推出来的

5.打印dp数组排错

题目代码:

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        int res = 1;
        Arrays.fill(dp, 1);
        for (int i = 1; i < dp.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
                res = Math.max(res, dp[i]);
            }
        }
        return res;
    }
}

LeetCode T674 最长连续递增序列

题目链接:674. 最长连续递增序列 - 力扣(LeetCode)

题目思路:

1.明确dp数组含义

dp[i]表示i为结尾元素的最长连续子数组

2.明确dp数组如何推导-递推公式

dp[i]这里只能由前面一个元素推出来,所以dp[i] = dp[i-1]+1

3.初始化dp数组

仍然初始化为1

4.确定遍历顺序

顺序遍历即可

5.打印dp数组排错

题目代码:

class Solution {
    public int findLengthOfLCIS(int[] nums) {
        int[] dp = new int[nums.length];
        int res = 1;
        Arrays.fill(dp, 1);
        for (int i = 1; i < dp.length; i++) {
            if (nums[i] > nums[i-1]) {
                dp[i] = dp[i-1] + 1;
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }
}

LeetCode T718 最长重复子数组

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

题目思路:

1.明确dp数组含义

dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。 (特别注意: “以下标i - 1为结尾的A” 标明一定是 以A[i-1]为结尾的字符串 )

至于为什么是i-1和j-1我会在最后给出解答

2.明确dp数组如何推导-递推公式

dp[i][j] = dp[i-1][j-1] + 1;

为啥是i-1和j-1呢?为啥不是别的呢,我在这里举个例子大家就能理解

假设nums1 = [1,2,3,2,1]

      nums2 = [3,2,1,4,7]

我们这里匹配到i = 4,j=2 他们的前一个状态是两者同时向前一个单位,是同时回退

3.初始化dp数组

dp[i][0]和dp[0][j]都是无意义的,全部初始化为0即可,其他的随便初始化为啥都可以,因为在遍历的过程中会被覆盖的

4.确定遍历顺序

先遍历哪个都行,顺序遍历,因为右下角的元素依赖于左上角元素产生

5.打印dp数组排错

注:这里的dp[i][j]并不是答案,答案在数组中出现,因为这里dp数组的含义是以i-1和j-1结尾的数组a和数组b的最大公共子数组,这里i-1和j-1不一定是最后的结尾位置.

这里dp数组的定义为啥不用i和j呢?

我们思考这样一个问题,如果dp[i][j]定义为以i结尾和以j结尾,那么这里的dp[i][0]就需要遍历一遍数组a,[0][j]需要遍历一遍数组b,这样代码显得冗余了.

题目代码:

class Solution {
    public int findLength(int[] nums1, int[] nums2) {
        int[][] dp = new int[nums1.length+1][nums2.length+1];
        int res = 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;
                res = Math.max(res,dp[i][j]);
            }
        }
        return res;
    }
}
相关文章
|
6月前
|
存储 C++ 索引
最长连续序列(每天刷力扣hot100系列)
本题使用哈希表法求最长连续序列。利用unordered_set存储去重元素,遍历集合时仅当num-1不存在时才作为起点向后扩展,统计连续长度,时间复杂度O(n),空间复杂度O(n)。相比unordered_map更高效,因无需存储值。
|
10月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
400 1
|
算法 C++
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
312 0
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
241 0
Leetcode第三十三题(搜索旋转排序数组)
|
C++
【LeetCode 12】349.两个数组的交集
【LeetCode 12】349.两个数组的交集
125 0
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
436 1
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
382 3
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
394 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
Python
【Leetcode刷题Python】1467. 两个盒子中球的颜色数相同的概率
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
278 0
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
384 1

热门文章

最新文章

下一篇
开通oss服务