两个求解代码类似的题目,对比记忆!!!
1143.最长公共子序列
法1:DP,考虑空串
Python
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
len1, len2 = len(text1), len(text2)
dp = [[0]*(len2 + 1) for _ in range(len1 + 1)]
for i in range(1, len1+1):
for j in range(1, len2+1):
if text1[i-1: i] == text2[j-1: 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[len1][len2]
Java
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int m = text1.length() + 1, n = text2.length() + 1; // 加1是在构建二维矩阵时增加空串情况, 简化计算
int[][] dp = new int[m][n];
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
return dp[m - 1][n - 1];
}
}
法2:DP,不考虑空串
代码会啰嗦很多,所以还是法1好哇!!!
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int m = text1.length(), n = text2.length();
int[][] dp = new int[m][n];
boolean existed = false;
for (int i = 0; i < n; ++i) {
dp[0][i] = (existed || text1.charAt(0) == text2.charAt(i)) ? 1 : 0;
if (dp[0][i] == 1) {
existed = true;
}
}
existed = false;
for (int i = 0; i < m; ++i) {
dp[i][0] = (existed || text1.charAt(i) == text2.charAt(0)) ? 1 : 0;
if (dp[i][0] == 1) {
existed = true;
}
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
if (text1.charAt(i) == text2.charAt(j)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
return dp[m - 1][n - 1];
}
}
516.最长回文子序列
Python
class Solution:
def longestPalindromeSubseq(self, s: str) -> int:
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n):
dp[i][i] = 1
for i in range(n-2, -1, -1):
for j in range(i+1, n):
if s[i: i+1] == s[j: j+1]:
dp[i][j] = dp[i+1][j-1] + 2
else:
dp[i][j] = max(dp[i+1][j], dp[i][j-1])
return dp[0][n-1]
Java
class Solution {
public int longestPalindromeSubseq(String s) {
int n = s.length();
int[][] dp = new int[n][n];
for (int i = 0; i < n; ++i) {
dp[i][i] = 1;
}
for (int i = n - 1; i >= 0; --i) {
for (int j = i + 1; j < n; ++j) {
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = (j - i == 1 ? 0 : dp[i + 1][j - 1]) + 2;
} else {
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][n - 1];
}
}