
解题思路:
- dp 数组的含义: dp[i][j] 是否为回文子串。
- 递推公式: dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]。
- dp 数组初始化: 单字符 dp[i][i] = true,双字符 dp[i][i + 1] = s.charAt(i) == s.charAt(i + 1)。
- 遍历顺序: 从 3 开始遍历,寻找最长回文子串。
- 打印 dp 数组
Java代码:
public class Solution {
public String longestPalindrome(String s) {
int n = s.length();
boolean[][] dp = new boolean[n][n];
int maxLen = 1;
int start = 0;
for (int i = 0; i < n; i++) dp[i][i] = true;
for (int i = 0; i < n - 1; i++) {
if (s.charAt(i) == s.charAt(i + 1)) {
dp[i][i + 1] = true;
maxLen = 2;
start = i;
}
}
for (int len = 3; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
if (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]) {
dp[i][j] = true;
maxLen = len;
start = i;
}
}
}
return s.substring(start, start + maxLen);
}
}
复杂度分析:
- 时间复杂度: O(n²)。
- 空间复杂度: O(1)。

解题思路:
- dp 数组的含义: 长度为 [0, i - 1] 的字符串 text1 与长度为 [0, j - 1] 的字符串 text2 的最长公共子序列为 dp[i][j]。
- 递推公式:
if (text1[i - 1] == text2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
- dp 数组初始化: dp[i][0] = 0,dp[0][j] = 0。
- 遍历顺序: 从小到大逐行遍历,确保左边和上边的 dp 数组有值。
- 打印 dp 数组
Java代码:
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int[][] dp = new int[text1.length() + 1][text2.length() + 1];
for (int i = 1; i <= text1.length() ; i++) {
char char1 = text1.charAt(i - 1);
for (int j = 1; j <= text2.length(); j++) {
char char2 = text2.charAt(j - 1);
if (char1 == char2) {
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[text1.length()][text2.length()];
}
}
复杂度分析:
- 时间复杂度: O(mn),其中 m 和 n 分别为 text1 和 text2 的长度。
- 空间复杂度: O(mn)。