LeetCode 题解工作台

交错字符串

给定三个字符串 s1 、 s2 、 s3 ,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串 : s = s 1 + s 2 + ... + s n t = t 1 + t 2 + ... +…

category

2

题型

code_blocks

7

代码语言

hub

3

相关题

当前训练重点

中等 · 状态·转移·动态规划

bolt

答案摘要

我们记字符串 的长度为 ,字符串 的长度为 ,如果 $m + n \neq |s_3|$,那么 一定不是 和 的交错字符串,返回 `false`。 接下来,我们设计一个函数 $dfs(i, j)$,表示从 的第 个字符和 的第 个字符开始,能否交错组成 的剩余部分。那么答案就是 $dfs(0, 0)$。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

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

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

  • 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

示例 2:

输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出:false

示例 3:

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

 

提示:

  • 0 <= s1.length, s2.length <= 100
  • 0 <= s3.length <= 200
  • s1s2、和 s3 都由小写英文字母组成

 

进阶:您能否仅使用 O(s2.length) 额外的内存空间来解决它?

lightbulb

解题思路

方法一:记忆化搜索

我们记字符串 s1s_1 的长度为 mm,字符串 s2s_2 的长度为 nn,如果 m+ns3m + n \neq |s_3|,那么 s3s_3 一定不是 s1s_1s2s_2 的交错字符串,返回 false

接下来,我们设计一个函数 dfs(i,j)dfs(i, j),表示从 s1s_1 的第 ii 个字符和 s2s_2 的第 jj 个字符开始,能否交错组成 s3s_3 的剩余部分。那么答案就是 dfs(0,0)dfs(0, 0)

函数 dfs(i,j)dfs(i, j) 的计算过程如下:

如果 imi \geq m 并且 jnj \geq n,那么说明 s1s_1s2s_2 都已经遍历完毕,返回 true

如果 i<mi < m 并且 s1[i]=s3[i+j]s_1[i] = s_3[i + j],那么说明 s1[i]s_1[i] 这个字符是 s3[i+j]s_3[i + j] 中的一部分,因此递归地调用 dfs(i+1,j)dfs(i + 1, j) 判断 s1s_1 的下一个字符能否和 s2s_2 的当前字符匹配,如果能匹配成功,就返回 true

同理,如果 j<nj < n 并且 s2[j]=s3[i+j]s_2[j] = s_3[i + j],那么说明 s2[j]s_2[j] 这个字符是 s3[i+j]s_3[i + j] 中的一部分,因此递归地调用 dfs(i,j+1)dfs(i, j + 1) 判断 s2s_2 的下一个字符能否和 s1s_1 的当前字符匹配,如果能匹配成功,就返回 true

否则,返回 false

为了避免重复计算,我们可以使用记忆化搜索。

时间复杂度 O(m×n)O(m \times n),空间复杂度 O(m×n)O(m \times n)。其中 mmnn 分别是字符串 s1s_1s2s_2 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        @cache
        def dfs(i: int, j: int) -> bool:
            if i >= m and j >= n:
                return True
            k = i + j
            if i < m and s1[i] == s3[k] and dfs(i + 1, j):
                return True
            if j < n and s2[j] == s3[k] and dfs(i, j + 1):
                return True
            return False

        m, n = len(s1), len(s2)
        if m + n != len(s3):
            return False
        return dfs(0, 0)
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    The candidate should explain how to fill the DP table, especially how the state transitions work for each character comparison.

  • question_mark

    A correct answer will involve explaining the transition between s1, s2, and s3 and handling edge cases like empty strings.

  • question_mark

    The interviewer should watch for the candidate's understanding of dynamic programming and how it can optimize the problem-solving process.

warning

常见陷阱

外企场景
  • error

    Misunderstanding the interleaving concept and attempting to rearrange characters rather than preserving the order from both strings.

  • error

    Failing to account for edge cases, such as when one or both strings are empty.

  • error

    Not properly filling the DP table or skipping necessary state transitions during the solution process.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    The problem could be modified by changing the constraints, such as limiting the maximum lengths of s1 and s2, which would require optimizations in the solution approach.

  • arrow_right_alt

    Another variant could involve allowing characters from s1 and s2 to overlap, requiring more sophisticated DP or backtracking techniques.

  • arrow_right_alt

    A variant could also introduce additional constraints like including special characters or uppercase letters, which would require adaptations in handling input.

help

常见问题

外企场景

交错字符串题解:状态·转移·动态规划 | LeetCode #97 中等