1. 题⽬链接:1143.最⻓公共⼦序列
2. 题⽬描述:
3. 解法(动态规划):
算法思路:
1. 状态表⽰:
对于两个数组的动态规划,我们的定义状态表⽰的经验就是:
i. 选取第⼀个数组[0, i] 区间以及第⼆个数组[0, j] 区间作为研究对象;
ii. 结合题⽬要求,定义状态表⽰。 在这道题中,我们根据定义状态表⽰为: dp[i][j] 表⽰: s1 的[0, i] 区间以及s2 的[0, j] 区间内的所有的⼦序列中,最 ⻓公共⼦序列的⻓度。
2. 状态转移⽅程:
分析状态转移⽅程的经验就是根据「最后⼀个位置」的状况,分情况讨论。 对于dp[i][j] ,我们可以根据s1[i] 与s2[j] 的字符分情况讨论:
i. 两个字符相同, s1[i] = s2[j] :那么最⻓公共⼦序列就在s1 的[0, i - 1] 以 及s2 的[0, j - 1] 区间上找到⼀个最⻓的,然后再加上s1[i] 即可。因此dp[i][j] = dp[i - 1][j - 1] + 1 ;
ii. 两个字符不相同, s1[i] != s2[j] :那么最⻓公共⼦序列⼀定不会同时以s1[i] 和s2[j] 结尾。那么我们找最⻓公共⼦序列时,有下⾯三种策略:
• 去s1 的[0, i - 1] 以及s2 的[0, j] 区间内找:此时最⼤⻓度为dp[i - 1][j] ;
• 去s1 的[0, i] 以及s2 的[0, j - 1] 区间内找:此时最⼤⻓度为dp[i ] [j - 1] ;
• 去s1 的[0, i - 1] 以及s2 的[0, j - 1] 区间内找:此时最⼤⻓度为 dp[i - 1][j - 1] 。 我们要三者的最⼤值即可。但是我们细细观察会发现,第三种包含在第⼀种和第⼆种情况⾥ ⾯,但是我们求的是最⼤值,并不影响最终结果。因此只需求前两种情况下的最⼤值即可。
综上,状态转移⽅程为: if(s1[i] == s2[j]) dp[i][j] = dp[i - 1][j - 1] + 1 ; if(s1[i] != s2[j]) dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) 。
3. 初始化:
a. 「空串」是有研究意义的,因此我们将原始dp 表的规模多加上⼀⾏和⼀列,表⽰空串。
b. 引⼊空串后,⼤⼤的⽅便我们的初始化。
c. 但也要注意「下标的映射关系」,以及⾥⾯的值要「保证后续填表是正确的」。 当s1 为空时,没有⻓度,同理s2 也是。因此第⼀⾏和第⼀列⾥⾯的值初始化为0 即可保证 后续填表是正确的。
4. 填表顺序:
根据「状态转移⽅程」得:从上往下填写每⼀⾏,每⼀⾏从左往右。
5. 返回值:
根据「状态表⽰」得:返回dp[m][n] 。
C++算法代码:
class Solution
{
public:
int longestCommonSubsequence(string text1, string text2)
{
int n1=text1.size(),n2=text2.size();
//优化
text1=' '+text1;
text2=' '+text2;
//建表
vector<vector<int>>dp(n1+1,vector<int>(n2+1));
//填表
for(int i=1;i<=n1;i++)
{
for(int j=1;j<=n2;j++)
{
if(text1[i]==text2[j])
{
dp[i][j]=dp[i-1][j-1]+1;
}
else
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
//返回值
return dp[n1][n2];
}
};
Java算法代码:
class Solution
{
public int longestCommonSubsequence(String s1, String s2)
{
// 1. 创建 dp 表
// 2. 初始化
// 3. 填表
// 4. 返回值
int m = s1.length(), n = s2.length();
s1 = " " + s1; s2 = " " + s2;
int[][] dp = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
if (s1.charAt(i) == s2.charAt(j))
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
return dp[m][n];
}
}
标签:状态表,int,s2,s1,算法,公共,序列,dp
From: https://blog.csdn.net/2301_79580018/article/details/143331189