【LeetCode 面试经典150题】97. Interleaving String 交错字符串

97. Interleaving String(交错字符串)

题目大意

Given strings s1, s2, and s3, find whether s3 is formed by an interleaving of s1 and s2.

An interleaving of two strings s and t is a configuration where s and t are divided into n and m substrings respectively, such that:

  • s = s1 + s2 + ... + sn
  • t = t1 + t2 + ... + tm
  • |n - m| <= 1
    The interleaving is s1 + t1 + s2 + t2 + s3 + t3 + ... or t1 + s1 + t2 + s2 + t3 + s3 + ...
    Note: a + b is the concatenation of strings a and b.

中文释义

给定字符串 s1s2s3,判断 s3 是否由 s1s2 交错形成。

两个字符串 st 的交错是一种配置,其中 st 被分成 nm 个子串,满足以下条件:

  • 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 是字符串 ab 的连接。

示例

  • 示例 1:
    在这里插入图片描述

    • 输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
    • 输出:true
    • 解释:一种获得 s3 的方式是:
      将 s1 分割为 “aa” + “bc” + “c”,将 s2 分割为 “dbbc” + “a”。
      交错这些分割,我们得到 “aa” + “dbbc” + “bc” + “a” + “c” = “aadbbcbcac”。
      由于 s3 可以通过交错 s1 和 s2 获得,我们返回 true。
  • 示例 2:

    • 输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
    • 输出:false
    • 解释:注意无法通过任何方式将 s2 与任何其他字符串交错以获得 s3。
  • 示例 3:

    • 输入:s1 = "", s2 = "", s3 = ""
    • 输出:true

限制条件

  • 0 <= s1.length, s2.length <= 100
  • 0 <= s3.length <= 200
  • s1s2s3 由小写英文字母组成。

进阶

你能只使用 O(s2.length) 额外空间解决这个问题吗?

解题思路

使用动态规划(DP)来解决问题。创建一个二维 dp 数组来判断 s1s2 的前缀是否可以交错形成 s3 的前缀。

步骤说明

  1. 初始化一个二维 dp 数组,dp[i][j] 表示 s1 的前 i 个字符和 s2 的前 j 个字符是否能交错形成 s3 的前 i+j 个字符。
  2. 对于每个 ij,检查 s1[i - 1] 是否等于 s3[i + j - 1] 以及 s2[j - 1] 是否等于 s3[i + j - 1],并据此更新 dp
  3. 返回 dp[s1.length][s2.length] 作为结果。

代码

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
        int length1 = s1.length(), length2 = s2.length(), length3 = s3.length();
        if (length1 + length2 != length3) return false;
        vector<vector<bool>> dp(length1 + 1, vector<bool>(length2 + 1, false));
        dp[0][0] = true;

        for (int i = 1; i <= length1; i++) dp[i][0] = dp[i - 1][0] && s1[i - 1] == s3[i - 1];
        for (int j = 1; j <= length2; j++) dp[0][j] = dp[0][j - 1] && s2[j - 1] == s3[j - 1];
        for (int i = 1; i <= length1; i++) {
            for (int j = 1; j <= length2; j++) {
                dp[i][j] = (dp[i - 1][j] && s1[i - 1] == s3[i + j - 1])
                        || (dp[i][j - 1] && s2[j - 1] == s3[i + j - 1]);
            }
        }
        return dp[length1][length2]; 
    }
};
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值