718.最长重复子数组
class Solution {
public:
int findLength(vector<int>& A, vector<int>& B) {
//动态规划,从后往前
//[i:]与[j:]的最长公共前缀
/*
dp[i][j] 的值从 dp[i + 1][j + 1] 转移得到,
首先计算 dp[len(A) - 1][len(B) - 1],最后计算 dp[0][0]。
*/
int n=A.size(),m=B.size();
vector<vector<int>> dp(n+1,vector<int>(m+1,0));
int ans=0;
for(int i=n-1;i>=0;i--){
for(int j=m-1;j>=0;j--){
//对应位置比较
dp[i][j] = A[i]==B[j] ?dp[i+1][j+1]+1:0;
ans=max(ans,dp[i][j]);
}
}
return ans;
}
};
1143.最长公共子序列
dp数组方便后面的数据就行计算,i从1开始,j从1开始,那么表示的是str1[i-1]范围内的字符。
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int m = text1.length();
int n = text2.length();
//dp[0][j],dp[i][0]没有意义
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
//对比字符串
for(int i = 1;i<=m;i++){
char c1 = text1.at(i-1);
for(int j=1;j<=n;j++){
char c2 = text2.at(j-1);
if(c1 == c2)
{
dp[i][j] = dp[i-1][j-1]+1;
}else{
//如果不相等的化,那么最大值可能来自于两种情况
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[m][n];
}
};
53.最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
dp[i]:表示以i结尾的子序列的和
1.延续和 2.重新开始计算
dp[i-1]+nums[i],nums[i]
dp[0]=nums[0]
动态规划:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==0) return 0;
vector<int> dp(nums.size());
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]);
if(dp[i]>result)result = dp[i];
}
return result;
}
};
贪心算法:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
//局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
int result = INT32_MIN;
int count = 0;
for(int i=0;i<nums.size();i++){
count +=nums[i];
//不断更新和
if(count>result){
result = count;
}
//丢弃前面的负数,直接从0开始
if(count<0) count = 0;
}
return result;
}
};
392.判断子序列
二维数组表示
最长公共子序列的长度等于s的长度
s一定要包含在t中的
- 确定递推公式
在确定递推公式的时候,首先要考虑如下两种操作,整理如下:
- if (s[i - 1] == t[j - 1])
- t中找到了一个字符在s中也出现了
- if (s[i - 1] != t[j - 1])
- 相当于t要删除元素,继续匹配
if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;,因为找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1(如果不理解,在回看一下dp[i][j]的定义)
if (s[i - 1] != t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];
class Solution {
public:
bool isSubsequence(string s, string t) {
vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
for (int i = 1; i <= s.size(); i++) {
for (int j = 1; j <= t.size(); j++) {
if (s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
else dp[i][j] = dp[i][j - 1];//如果t[j-1]位置不匹配,那就等于s和t[j-2]的匹配个数
}
}
if (dp[s.size()][t.size()] == s.size()) return true;
return false;
}
};