718. 最长重复子数组
//dp[i][j] 以下标i-1为结束和j-1为结束的最长重复子数组的长度
// if nums[i-1]=nums[j-1]
// dp[i][j] = dp[i-1][j-1]+1;
//dp[i][0]=0; dp[0][j]=0 没有意义,但是符合之后的计算 比如dp[1][1]=dp[0][0]+1
class Solution {
public:
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;
}
if (dp[i][j]>result) result=dp[i][j];
}
}
// for (int i=0; i<=nums1.size(); i++){
// for (int j=0; j<=nums2.size(); j++){
// cout << dp[i][j] <<" ";
// }
// cout << endl;
// }
return result;
}
};
1143.最长公共子序列
// dp[i][j] text1从0到i-1与text2从0到j-1最长的公共子序列长度
// if (text1[i-1]==text2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
// else dp[i][j]=max(dp[i-1][j], dp[i][j-1]);
// dp[0][j] dp[i][0] = 0
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
vector<vector<int>> dp(text1.size()+1, vector<int>(text2.size()+1, 0));
int result=0;
for (int i=1; i<text1.size()+1; i++){
for (int j=1; j<text2.size()+1; j++){
if (text1[i-1]==text2[j-1]) {
dp[i][j] = dp[i-1][j-1]+1;
}
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
result = max(dp[i][j], result);
}
}
// for (int i=0; i<text1.size()+1; i++){
// for (int j=0; j<text2.size()+1; j++){
// cout << dp[i][j] <<" ";
// }
// cout << endl;
// }
return dp[text1.size()][text2.size()];
}
};
注意dp[i][j]是text1从0-i和text2从0-j中最长的公共子序列长度
1035.不相交的线
//问题可以被转化为求最大公共子序列,因为只要对应元素在右侧相等就一定不会出现相交的情况
//dp[i][j] num1从0-i与num2从0-j的最大公共子序列长度
// if (nums1[i-1]==nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
// else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
// dp[i][0]=0 dp[0][j]=0
class Solution {
public:
int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>> dp(nums1.size()+1, vector<int>(nums2.size()+1, 0));
for (int i=1; i<nums1.size()+1; i++){
for (int j=1; j<nums2.size()+1; j++){
if (nums1[i-1]==nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
return dp[nums1.size()][nums2.size()];
}
};
53. 最大子数组和
//dp[i]以i为结尾的最大子数组和
//dp[i]=max(dp[i-1]+nums[i], nums[i]) 如果之前的和为负就直接取当前元素为最大值
//dp[0]=nums[0]
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int maxSum=nums[0];
vector<int>dp(nums.size(), 0);
dp[0]=nums[0];
for (int i=1; i<nums.size(); i++)
{
dp[i]=max(dp[i-1]+nums[i], nums[i]);
maxSum = max(maxSum, dp[i]);
}
// for (int i : dp) cout <<i<<" ";
// cout << endl;
return maxSum;
}
};