【多维动态规划】Leetcode 97. 交错字符串【中等】

交错字符串

给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。

两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空
子字符串

子字符串 是字符串中连续的 非空 字符序列。

  • s = s1 + s2 + ... + sn
  • t = t1 + t2 + ... + tm
  • |n - m| <= 1
  • 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...

注意:a + b 意味着字符串 a 和 b 连接。

示例 1:


输入 :s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出:true

解题思路

定义一个二维布尔数组 dp,其中 dpij 表示 s3 的前 i + j 个字符是否可以由s1 的前 i 个字符和 s2 的前 j 个字符交错组成。具体的递推关系如下:

初始条件:

  • dp00 = true,表示两个空字符串可以组成空字符串。

递推关系:

  • 如果 dpi-1j 为真且 s1i-1 == s3i + j - 1,则 dpij = true。

    dpi-1j 表示 s3 的前 i + j - 1 个字符可以通过 s1 的前 i-1 个字符和 s2 的前 j 个字符交错组成。

    如果 s1 的第 i 个字符 s1i-1 等于 s3 的第 i + j 个字符 s3i + j - 1,

    则可以在 s3 的前 i + j - 1 个字符的基础上加上 s1 的第 i 个字符组成 s3 的前 i + j 个字符。

    因此,dpij = true。

  • 同理,如果 dpij-1 为真且 s2j-1 == s3i + j - 1,则 dpij = true。

最终结果:

  • dps1.length()s2.length() 表示 s3 是否可以由 s1 和 s2 交错组成。

Java实现

java 复制代码
public class InterleavingString {
    public boolean isInterleave(String s1, String s2, String s3) {
        int m = s1.length();
        int n = s2.length();
        
        if (m + n != s3.length()) {
            return false;
        }
        
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        
        // 初始化第一列
        for (int i = 1; i <= m; i++) {
            dp[i][0] = dp[i-1][0] && s1.charAt(i-1) == s3.charAt(i-1);
        }
        
        // 初始化第一行
        for (int j = 1; j <= n; j++) {
            dp[0][j] = dp[0][j-1] && s2.charAt(j-1) == s3.charAt(j-1);
        }
        
        // 填充 dp 表
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = (dp[i-1][j] && s1.charAt(i-1) == s3.charAt(i + j - 1)) || 
                           (dp[i][j-1] && s2.charAt(j-1) == s3.charAt(i + j - 1));
            }
        }
        
        return dp[m][n];
    }

    // 测试用例
    public static void main(String[] args) {
        InterleavingString solution = new InterleavingString();
        System.out.println(solution.isInterleave("aabcc", "dbbca", "aadbbcbcac"));  // 期望输出: true
        System.out.println(solution.isInterleave("aabcc", "dbbca", "aadbbbaccc"));  // 期望输出: false
    }
}

时间空间复杂度

  • 时间复杂度:O(m * n),其中 m 是 s1 的长度,n 是 s2 的长度,需要遍历整个 dp 数组。
  • 空间复杂度:O(m * n),需要一个二维数组 dp 存储中间结果。
相关推荐
Nil2084 分钟前
leetcode 322零钱兑换
算法·leetcode·职场和发展
海绵宝宝转agent9 分钟前
2026-10-9 leetcode100刷题+面经整理
笔记·算法·面试
yi01119 分钟前
DAY24: LeetCode 167:两数之和 II|从暴力枚举到左右双指针
笔记·python·算法·leetcode·二分查找·双指针
木井巳20 分钟前
【BFS 解决拓扑排序】课程表
java·算法·leetcode·广度优先·宽度优先·推荐算法·图搜索算法
Logic10133 分钟前
C语言/数据结构数位DP题解:平滑排列数字统计——区间内相邻位差不超过K的数字个数
c语言·数据结构·动态规划·时间复杂度·数位dp·算法题·前导零处理
扶风ff40 分钟前
练题簿在线免费刷题:会员线下组卷、Word 试卷与成绩导入,课堂检测更方便
java·开发语言·算法·小程序·word
yi0111 小时前
LeetCode 15:三数之和|排序 + 双指针,如何避免重复答案?
笔记·python·算法·leetcode·双指针
-dzk-1 小时前
【多维动态规划】LC 1143.最长公共子序列
算法·动态规划
C++ 老炮儿的技术栈1 小时前
char (*csConnectName)[256]; 和 char csConnectName [256] 有什么区别
java·c语言·开发语言·c++·人工智能·算法·c
Omics Pro1 小时前
全新可重分析!代谢组质谱专用
数据库·人工智能·算法·机器学习·自然语言处理