动态规划(7) 编辑距离(1)
300最长递增子序列
- 递推公式的含义,为了从dp[j]中取出符合要求的最长的子序列
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
//dp的含义,dp[j]表示当前递增子序列长度的最大值
int n=nums.size();
vector<int> dp(n,1);
int mx=1;
for(int i=1;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(nums[i]>nums[j])
{
dp[i]=max(dp[i],dp[j]+1);
}
}
mx=max(mx,dp[i]);
}
return mx;
}
};
674最长连续递增序列
因为是连续子序列,所以也比较简单,只要检测前一个就行了
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int n=nums.size();
vector<int> dp(n,1);
int mx=1;
for(int i=1;i<n;i++)
{
if(nums[i]>nums[i-1])
{
dp[i]=dp[i-1]+1;
}
mx=max(mx,dp[i]);
}
return mx;
}
};
718最长重复子数组
- 注:子数组是连续的,所以这题比较简单
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
//dp[i][j]的含义,以i j为结尾的最长的子数组的长度
//dp[i][j]由dp[i-1][j-1]+1推来
int n=nums1.size();
int m=nums2.size();
int mx=0;
vector<vector<int>> dp(n+2,vector<int>(m+1,0));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(nums1[i-1]==nums2[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
}
if(dp[i][j]>mx)
mx=dp[i][j];
}
}
return mx;
}
};
1143最长公共子序列
最关键的就是:
//和公共子数组比起来多了这一步,因为序列关系是可以继承的
else
{
dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
}
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int n=text1.size();
int m=text2.size();
int mx=0;
vector<vector<int>> dp(n+1,vector<int>(m+1,0));
//dp含义,以i j为结尾的两个字符串,最长公共子序列的长度
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;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]);
}
if(dp[i][j]>mx)
{
mx=dp[i][j];
}
}
}
return mx;
}
};