交错字符串
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 28 ms, 内存: 16.1 MB
/*
* 题目思路:
* 使用动态规划来解决这个问题,与上述 Java 版本相同。但由于动态规划需要嵌套循环,因此 Java Stream 并不是特别适合这种情况。仍然给出 Stream 的代码来尝试简化一些操作。
*/
import java.util.stream.IntStream;
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length()) {
return false;
}
boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
dp[0][0] = true;
IntStream.rangeClosed(0, s1.length()).forEach(i ->
IntStream.rangeClosed(0, s2.length()).forEach(j -> {
if (i > 0) {
dp[i][j] = dp[i][j] || (dp[i-1][j] && s1.charAt(i-1) == s3.charAt(i+j-1));
}
if (j > 0) {
dp[i][j] = dp[i][j] || (dp[i][j-1] && s2.charAt(j-1) == s3.charAt(i+j-1));
}
})
);
return dp[s1.length()][s2.length()];
}
}
解释
方法:
此题解采用动态规划的方法来解决交错字符串问题。首先,我们定义一个二维的布尔数组dp,其中dp[i][j]表示字符串s1的前i个字符和s2的前j个字符是否能交错组成s3的前i+j个字符。初始化dp[0][0]为True,表示空字符串可以组成空字符串。然后,初始化第一行和第一列,分别表示只使用s1或s2时的情况。对于矩阵中剩余的元素,通过检查s1的当前字符是否与s3的对应字符匹配来更新dp[i][j],如果匹配,则参考左侧的dp值(即不包括当前字符的s1和s2的组合)。同理,检查s2的当前字符是否匹配,并参考上方的dp值。最终,dp[n1][n2]给出了整个字符串的匹配结果。
时间复杂度:
O(n1 * n2)
空间复杂度:
O(n1 * n2)
代码细节讲解
🦆
为什么在初始化dp数组时,只有当s3的第i个字符与s1的第i个字符匹配时才设置dp[i][0]为True?
▷🦆
在动态规划矩阵的更新规则中,dp[i][j] = (dp[i-1][j] and s1[i-1] == s3[i+j-1]) or (dp[i][j-1] and s2[j-1] == s3[i+j-1]),这个表达式是如何确保字符串s3可以由s1和s2交错组成的?
▷🦆
为什么在判断s1和s2的长度之和是否等于s3的长度时,只返回False?是否存在其他情况需要提前返回结果?
▷