代码随想录算法训练营第四十一天| 1143.最长公共子序列 1035.不相交的线 53. 最大子序和
1143.最长公共子序列
要求:
可以跳过,找出来最长符合的节点
难点:
如何跳过了之后仍然保留之前的值
思路:
如果不符,并不是dp[i-1][j-2]等于之前的值,而是dp[i][j] 等于它的相关节点
以上很重要
代码 :
1 // 要求: 两个子数组,可以删减跳过,找出最长的长度 2 // 思路:dp[n][m] 代表第n-1 m-1的重复长度 3 // 因为个别字节可以跳过,不可以+1,再加一个数组 4 // 遍历dp[n][m] = dp[n][m-1] 5 // 6 // 可以删减,之前的思路: 7 // 1,dp[n]以N为结尾,然后遍历0-n有没有一样的节点,然后放进去 8 // 9 // 思路: 10 // 1,如果当前节点相等,那么找到上一个节点中最大的值,在后面+1 11 // 12 // 新思路: (如何跳过节点) 13 // 如果不满足, dp[i][j] = max(dp[i-1][j],dp[i][j-1]) 向左和上,保持一致 14 // 15 int longestCommonSubsequence(string text1, string text2) { 16 int result = 0; 17 18 vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0)); 19 20 for (int i = 1; i <= text1.size(); i++) 21 { 22 for (int j = 1; j <= text2.size(); j++) 23 { 24 if (text1[i - 1] == text2[j - 1]) 25 { 26 dp[i][j] = dp[i - 1][j - 1] + 1; 27 } 28 else 29 { 30 dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]); 31 } 32 33 result = result > dp[i][j] ? result : dp[i][j]; 34 } 35 } 36 37 return result; 38 }
1035.不相交的线
要求:
相等,保证顺序,不可相交
他说的不可相交,其实就跟上一题的,保证顺序,他们的最长子序列一样
因为子序列也是保证顺序的,尽管看着for()for() 两个for 都把所有相等的节点遍历了一遍,但是其实保证顺序的,
例如 142 和 1 2 4,他们是 142 12这两个比较和 14 124这两个比较
代码:
同上
53. 最大子序和
要求:
找到最大的数组和
思路:
dp[i] = max(dp[i-1]+nums[i],nums[i]);
代码:
1 // 要求:需要连续,返回最大的和 2 // 贪心的做法:如果是负数,那么就舍弃掉,不累加 3 // 动态规划 4 // dp[n] 以N为结尾的最大数组和 5 // 6 // dp[i] 7 // 如果 dp[i-1]为负数,那么就是nums[i] 8 // 如果不是负数,那么就是 dp[i-1]+nums[i] 9 // 10 int maxSubArray(vector<int>& nums) { 11 if (nums.size() == 1) return nums[0]; 12 13 int result = nums[0]; 14 vector<int>dp(nums.size(), 0); 15 dp[0] = nums[0]; 16 17 for (int i = 1; i < nums.size(); i++) 18 { 19 if (dp[i - 1] > 0) dp[i] = dp[i - 1] + nums[i]; 20 else dp[i] = nums[i]; 21 22 result = result > dp[i] ? result : dp[i]; 23 } 24 25 return result; 26 }