1143.最长公共子序列
解题思路
这题和最长重复子数组的区别就是:这题并不是连续的
对于两个数组进行比较,我们一般使用二维数组即可
1.dp[i][j] 以i-1结尾的nums1,和以j-1结尾的nums2的最长公共子序列
以i-1结尾便于初始化
2.递推公式
if(nums[i-1]==nums[j-1]) dp[i][j] = dp[i-1][j-1]+1 //如果相同,则同时回退
else dp[i][j] = max(dp[i][j-1], dp[i-1][j])
3.初始化
dp[i][0] dp[0][j]都是0
4.遍历顺序
从左到右,从上到下推导
因为这题是求最长公共子序列,结果肯定在结尾处取得
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
vector<vector<int>> dp(text1.size()+1,vector<int>(text2.size()+1,0)); //i-1和j-1结尾的最长公共子序列
for(int i = 1 ;i<=text1.size() ; i++)
{
for(int j =1 ; j <= text2.size() ; j++ )
{
if(text1[i-1]==text2[j-1]) dp[i][j] = dp[i-1][j-1] + 1; //如果相等,则同时回退
else dp[i][j] = max(dp[i][j-1],dp[i-1][j]); //如果不相等,回退一位查看,由前面的推出来,与连续不同的是,连续遇到不相同的,要从0开始推,非连续只需要从前面已知的长度继续开始推
}
}
return dp[text1.size()][text2.size()];
}
};
1035.不相交的线
这一题和上一题是一样的,包括代码,其实求得就是最长公共子序列
class Solution {
public:
int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0)); //i-1和j-1结尾的最长公共子序列
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; //如果相等,则同时回退
else dp[i][j] = max(dp[i][j-1],dp[i-1][j]); //如果不相等,回退一位查看,由前面的推出来,与连续不同的是,连续遇到不相同的,要从0开始推,非连续只需要从前面已知的长度继续开始推
}
}
return dp[nums1.size()][nums2.size()];
}
};
53. 最大子数组和
解题思路
本次主要掌握动态规划的思路
1.dp[i] 以nums[i]为结尾的最大连续子数组的和
2.递推公式
dp[i] = max(nums[i] , dp[i-1]+nums[i]); 要么是前面的都不要了,就拿自身,要么就延续前面的
3.初始化
dp[0] = nums[0]
4.遍历顺序
从头到尾,结果在中间记录
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> dp(nums.size(),0);
dp[0]=nums[0];
int result = dp[0];
for(int i =1 ;i<nums.size();i++)
{
dp[i] = max( dp[i-1]+nums[i], nums[i] );
result = max(result,dp[i]);
}
return result;
}
};