最长公共子序列
从最后一个元素开始思考,如果s[i]==t[j],毫无疑问,它们是公共的,直接考虑s[i-1],t[j-1]即可,如果不相等,就保留一个,舍去另一个,考虑s[i-1],t[j]与考虑s[i],t[j-1]两种情况的最大值即可,
class Solution {
public:
vector>cache=vector>(1005,vector(1005,-1));
int dfs(int i,int j,string&s,string&t)
{
if(i<0||j<0)
return 0;
if(cache[i][j]!=-1)
{
return cache[i][j];
}
int res;
if(s[i]==t[j])
{
res=dfs(i-1,j-1,s,t)+1;
}
else
{
res=max(dfs(i-1,j,s,t),dfs(i,j-1,s,t));//选j不选i,选i不选j
}
cache[i][j]=res;
return res;
}
int longestCommonSubsequence(string s, string t) {
return dfs(s.size()-1,t.size()-1,s,t);
}
};
class Solution {
public:
int longestCommonSubsequence(string s, string t) {
int n=s.size(),m=t.size();
vector>f(n+5,vector(m+5,0));
for(int i=0;i
编辑距离
如果s[i]==t[j],它们是相同的,考虑s[i-1],t[j-1]即可,如果不同,有三种方式,删除s的最后一个字母,即考虑,s[i-1],t[j],对a插入b的一个字母,相当于删除b,即考虑s[i],t[j-1],还可以替换,直接让这个位置的字母相同,即考虑,s[i-1],t[j-1],三种情况取个最小值,再加1.
class Solution {
public:
vector>cache=vector>(505,vector(505,-1));
int dfs(int i,int j,string&word1,string&word2)
{
if(i<0)
return j+1;
if(j<0)
return i+1;
if(cache[i][j]!=-1)
return cache[i][j];
int res;
if(word1[i]==word2[j])
res=dfs(i-1,j-1,word1,word2);
else
res=min({dfs(i,j-1,word1,word2),dfs(i-1,j,word1,word2),dfs(i-1,j-1,word1,word2)})+1;
cache[i][j]=res;
return res;
}
int minDistance(string word1, string word2) {
return dfs(word1.size()-1,word2.size()-1,word1,word2);
}
};
class Solution {
public:
int minDistance(string word1, string word2) {
int n=word1.size(),m=word2.size();
int f[n+5][m+5];
for(int i=0;i<=n;i++)f[i][0]=i;
for(int j=0;j<=m;j++)f[0][j]=j;
for(int i=0;i
最长严格递增子序列
以枚举选哪个作为切入点,而不是选或不选,枚举每个位置作为递增子序列的终点,取最大值.从这个终点再往前枚举,计算最长递增子序列,最后得到每个点作为终点的最长递增子序列长度,取所有点的最大值
class Solution {
public:
vectorcache=vector(2505,-1);
int dfs(int i,vector&nums)
{
if(cache[i]!=-1)
return cache[i];
int res=0;
for(int j=0;j& nums) {
int ans=0;
for(int i=0;i
class Solution {
public:
int lengthOfLIS(vector& nums) {
int n=nums.size(),f[n];
for(int i=0;i
值得一说的是,将该数组去重并排序再与原数组求最长公共子序列也可以求得答案