上海专业的网站建设,php网站模块修改,陕西网站开发联系方式,云建站的正确步骤300.最长递增子序列
文章讲解/视频讲解
题目描述#xff1a;
给你一个整数数组 nums #xff0c;找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列#xff0c;删除#xff08;或不删除#xff09;数组中的元素而不改变其余元素的顺序。例如#xff…300.最长递增子序列文章讲解/视频讲解题目描述给你一个整数数组 nums 找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列删除或不删除数组中的元素而不改变其余元素的顺序。例如[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。示例 1输入nums [10,9,2,5,3,7,101,18]输出4解释最长递增子序列是 [2,3,7,101]因此长度为 4 。示例 2输入nums [0,1,0,3,2,3]输出4示例 3输入nums [7,7,7,7,7,7,7]输出1提示1 nums.length 2500-10^4 nums[i] 104思路1.dp数组及其下标含义这是本题的重中之重本题的dp[i]表示i之前包括nums[i]结尾的最长递增子序列2.状态转移方程位置i的最长递增序列等于 j 从 0 到 i - 1的最长递增序列 1位置i本身也就是我们去找最大的dp[j] 1if (nums[i] nums[j]) {dp[i] Math.max(dp[i], dp[j] 1)}3.dp数组的初始化所有位置最开始起码都是1所以全部初始化为14.确定遍历顺序本题一共有两层for循环外层遍历i内层遍历j外层遍历的i是一定要从小到大遍历的要不然拿不到前面的数据内层的j无所谓从前还是从后只要是0到i - 1这个范围就行了5.举例推导dp数组输入[0,1,0,3,2]dp数组的变化如下如果代码写出来但一直AC不了那么就把dp数组打印出来看看对不对代码示例function lengthOfLIS(nums: number[]): number { const length: number nums.length const dp: number[] new Array(length).fill(1) let res: number 0 for (let i 0; i length; i) { for (let 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 };674.最长连续递增数列文章讲解/视频讲解题目描述给定一个未经排序的整数数组找到最长且 连续递增的子序列并返回该序列的长度。连续递增的子序列 可以由两个下标 l 和 rl r确定如果对于每个 l i r都有 nums[i] nums[i 1] 那么子序列 [nums[l], nums[l 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。示例 1输入nums [1,3,5,4,7]输出3解释最长连续递增序列是 [1,3,5], 长度为3。尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的因为 5 和 7 在原数组里被 4 隔开。示例 2输入nums [2,2,2,2,2]输出1解释最长连续递增序列是 [2], 长度为1。提示0 nums.length 10^4-10^9 nums[i] 10^9思路本题相比上一题其实跟像退阶版本因为连续意味着我们不必比较nums[j]和nums[i]只需要比较nums[i]和nums[i -1]的大小即可1.确定dp数组及其下标含义dp[i]表示以i为结尾的连续递增子序列为dp[i]2.确定递推公式如果 nums[i] nums[i - 1]那么以 i 为结尾的连续递增的子序列长度 一定等于 以i - 1为结尾的连续递增的子序列长度 1 。即dp[i] dp[i - 1] 13.dp数组的初始化虽然是连续递增子序列但是每个序列开始时起码都为1依旧全部初始化为14.确定遍历顺序由于dp[i]依赖于dp[i - 1]所以一定是从前往后遍历的5.举例推导dp数组已输入nums [1,3,5,4,7]为例dp数组状态如下注意这里要取dp[i]里的最大值所以dp[2]才是结果代码示例function findLengthOfLCIS(nums: number[]): number { const length: number nums.length const dp: number[] new Array(length).fill(1) let res: number 1 for (let i 1; i length; i) { if (nums[i] nums[i - 1]) { dp[i] dp[i - 1] 1 } res Math.max(res, dp[i]) } return res };718.最长重复子数组文章讲解/视频讲解题目描述给两个整数数组 A 和 B 返回两个数组中公共的、长度最长的子数组的长度。示例输入A: [1,2,3,2,1]B: [3,2,1,4,7]输出3解释长度最长的公共子数组是 [3, 2, 1] 。提示1 len(A), len(B) 10000 A[i], B[i] 100思路本题我们考虑用一个二维数组记录两个字符串这样就能轻松比较二者重复字母1.确定dp数组及其下标含义dp[i][j] 以下标i - 1为结尾的A和以下标j - 1为结尾的B最长重复子数组长度为dp[i][j]。 特别注意 “以下标i - 1为结尾的A” 标明一定是 以A[i-1]为结尾的字符串 注意这里这么写了就表示dp数组就一定是从dp[1][1]开始的2.确定递推公式根据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数组的初始化按照dp数组的定义来讲dp[0][0]其实没有意义你总不能是以下标-1为结尾的A数组吧。但是为了遍历能正常进行我们还是把dp[0][0]设置成0只有这样dp[1][1]才能等于dp[0][0] 1后续的dp数组也才能够递增下去4.确定遍历顺序本题外层放a还是b其实无所谓最重要的确保双层循环即可而且从前往后遍历5.举例推导dp数组拿示例1中A: [1,2,3,2,1]B: [3,2,1,4,7]为例画一个dp数组的状态变化如下代码示例function findLength(nums1: number[], nums2: number[]): number { const length1: number nums1.length const length2: number nums2.length const dp: number[][] new Array(length1 1).fill(0).map(_ new Array(length2 1).fill(0)) let res: number 0 for (let i 1; i length1; i) { for (let j 1; j length2; j) { if (nums1[i - 1] nums2[j - 1]) { dp[i][j] dp[i - 1][j - 1] 1 res Math.max(dp[i][j], res) } } } return res };