由子序列构造的最长回文串的长度
难度:
标签:
题目描述
代码结果
运行时间: 868 ms, 内存: 16.7 MB
/*
题目思路:
1. 通过使用 Java Stream API 来实现与 Java 方法相同的逻辑。
2. 需要构造 dp 数组来存储动态规划过程中的结果。
*/
public class Solution {
public int longestPalindrome(String word1, String word2) {
int n = word1.length();
int m = word2.length();
String s = word1 + word2;
int len = s.length();
int[][] dp = new int[len][len];
int maxLen = 0;
// 初始化 dp 数组
IntStream.range(0, len).forEach(i -> dp[i][i] = 1);
// 动态规划求解最长回文子序列长度
IntStream.range(2, len + 1).forEach(l -> {
IntStream.range(0, len - l + 1).forEach(i -> {
int j = i + l - 1;
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = dp[i + 1][j - 1] + 2;
if (i < n && j >= n) {
maxLen = Math.max(maxLen, dp[i][j]);
}
} else {
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
}
});
});
return maxLen;
}
}
解释
方法:
这个题解使用动态规划来寻找连接后的字符串中最长的回文子序列的长度。首先,将两个字符串word1和word2连接成一个新字符串w。然后利用一个二维动态规划的技巧,但只使用一维数组dp来减少空间复杂度。遍历这个合并后的字符串,利用两层循环,外层从后向前,内层从外层的当前索引向后,来更新dp数组。若字符w[i]和w[j]相同,则dp[j]被更新为dp[j-1]加2;否则,dp[j]为dp[j]和dp[j-1]的最大值。特别地,如果i属于word1的部分,而j属于word2的部分,且形成了新的回文字符串,则更新最大长度res。最后,返回res。
时间复杂度:
O(n^2)
空间复杂度:
O(n)
代码细节讲解
🦆
如何确保连接的子序列最终形成的字符串中包含的回文串是最长的,而不仅仅是任意回文串?
▷🦆
在动态规划中,当w[i] != w[j]时,dp[j]取dp[j]与newDp[j-1]中的较大值。这种方法为何能确保跟踪到最长的回文长度?
▷🦆
为什么在初始化newDp数组时,设置newDp[i] = 1,这代表了什么?
▷🦆
题解中提到,只有当i属于word1且j属于word2时,才更新最大长度res。为什么这样的条件是必要的?
▷