leetcode
leetcode 2951 ~ 3000
交错字符串

交错字符串

难度:

标签:

题目描述

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数组时,dp[i][0]为True表示仅使用s1的前i个字符就能组成s3的前i个字符。如果在某个位置i,s3的第i个字符与s1的第i个字符不匹配,则意味着s1的前i个字符无法单独组成s3的前i个字符,因此在这种情况下将dp[i][0]设置为False。初始化过程中的这种匹配检查是为了确定在仅使用s1字符时,各个阶段是否能够满足交错组成s3的条件。
🦆
在动态规划矩阵的更新规则中,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交错组成的?
这个更新规则确保了只有当当前字符匹配时,我们才考虑将其加入到交错字符串中。这里dp[i][j]的更新依赖于两个条件:1) dp[i-1][j]和s1[i-1]与s3[i+j-1]的匹配,表示如果不包括s1的当前字符,之前的字符已经可以组成s3的前i+j-1个字符;2) dp[i][j-1]和s2[j-1]与s3[i+j-1]的匹配,表示如果不包括s2的当前字符,之前的字符已经可以组成s3的前i+j-1个字符。这种方法确保了只有在字符完全匹配的情况下,我们才认为s1的前i个字符和s2的前j个字符能够交错组成s3的前i+j个字符。
🦆
为什么在判断s1和s2的长度之和是否等于s3的长度时,只返回False?是否存在其他情况需要提前返回结果?
在这个算法中,如果s1和s2的长度之和不等于s3的长度,那么它们无法组成s3,因为字符总数不匹配,直接返回False。除此之外,如果s1和s2为空字符串且s3也为空,那么应该返回True,但这种情况已经在dp[0][0]的初始化中处理了。因此,不等长的直接判断是必要的,且在这种情况下提前返回结果是合理的,其他情况则需要通过动态规划的过程来确定结果。

相关问题