代码随想录算法训练营第四十天| 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组
300.最长递增子序列
要求:
可以删减任意个节点,最后保存最大的递增长度
难点:
4 10 4 8 9
如何 保证全局的视角,看到很前面的节点是否大于当前的节点,而不是仅仅记录状态
思路:
dp[n] , 当子序列的末尾为N时,它的最大子序列长度
也就意味着,N在它的子序列中是最大的,遍历这个N之前的所有序列,如果比他们大,就+1
注意, 2 1 3, 虽然3 比1 2都大,但是为2,
如何做到这一点?
dp[i] = max(dp[i], dp[j]+1),所以2 当时是1,1也是1,所以3是2,而不会是3
代码:
1 // 要求:最长严格递增子序列长度 可以删除任意节点 2 // 难点:如何全局的看到后面的情况0 3 // 4 // dp[n] : 以nums[n]为结尾的最长递增子序列的长度!!! 很重要 5 // 6 // dp[i] = 因为是以I为结尾,所以需要把I之前的所有节点都遍历一下,找到目前最长的子序列长度 7 // 8 int lengthOfLIS(vector<int>& nums) { 9 if (nums.size() == 1) return 1; 10 11 vector<int>dp(nums.size(), 1); 12 13 for (int i = 1; i < nums.size(); i++) 14 { 15 // 从而实现了全局,也就是4 10 4 8 9 的问题, dp[i] = dp[i-1]+1 , dp[i-1] 16 for (int j = 0; j < i; j++) 17 { 18 if (nums[j] < nums[i]) 19 { 20 //很巧妙 一定要会用 21 dp[i] = max(dp[i], dp[j] + 1); 22 } 23 } 24 } 25 26 int result = INT_MIN; 27 for (int i = 0; i < dp.size(); i++) 28 { 29 result = result > dp[i] ? result : dp[i]; 30 } 31 32 return result; 33 }
674. 最长连续递增序列
比较简单:
代码
1 // 要求:这个必须是连续的递增子序列,不可以任意删减 2 // 3 // 4 int findLengthOfLCIS(vector<int>& nums) { 5 if (nums.size() == 1) return 1; 6 7 vector<int> dp(nums.size(), 1); 8 int result = INT_MIN; 9 for (int i = 1; i < nums.size(); i++) 10 { 11 if (nums[i] > nums[i - 1]) 12 { 13 dp[i] = dp[i - 1] + 1; 14 } 15 16 result = result > dp[i] ? result : dp[i]; 17 } 18 19 return result; 20 }
718. 最长重复子数组
要求:
有两个数组,求出来里面最长的重复子数组:也就是,最长的交集
思路:
dp[n][m] 第一个数组的第n-1 和 第二个数组的m-1中的重复的子数组
细节分析:
对于第N-1个nums1数组,他会和nums2数组的每个元素都进行比较,然后如果和 2 3,都相等,那么这两个都会+1
紧接着下一个nums1,会和nums2比较,如果相等,那么就会在前面的基础上累加
代码:
// 要求:字符串匹配,找出来最长的子字符串 KMP算法需要再复习 // // 最短的那个子数组为字符串匹配的来源 // // dp[n],第N个匹配的子序列长度,需要记录N 在1中匹配的index 列表 // // 难点:可能1 2 1 3 用1匹配,那么有两个节点 // // 新思路:dp[n][m] 在第n-1 m-1的子序列中重复数组的长度 // // nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7] // // dp[i][j] = dp[i-1][j-1]+1 // int findLength(vector<int>& nums1, vector<int>& nums2) { int result = 0; vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0)); for (int i = 1; i <= nums1.size(); i++) { for (int j = 1; j <= nums2.size(); j++) { if (nums1[i-1] == nums2[j-1]) { dp[i][j] = dp[i - 1][j - 1] + 1; result = result > dp[i][j] ? result : dp[i][j]; } } } return result; }