当前位置: 首页>编程语言>正文

交错字符串

题目链接

交错字符串

题目描述

注意点

  • s1、s2、和 s3 都由小写英文字母组成
  • 0 <= s1.length, s2.length <= 100
  • 0 <= s3.length <= 200
  • 能否仅使用 O(s2.length) 额外的内存空间来解决它

解答思路

  • 最初想到的是使用深度优先遍历,使用指针指向当前s3需要的字符、当前能取s1和s2的相应字符,如果都不是s3需要的字符,则说明当前情况不满足题意,否则需要取s1或s2中满足的字符并移动指针继续进行深度优先遍历。但是该方法时间复杂度不满足
  • 参考题解使用动态规划解决本题,思路为:使用二维数组dp存储是否是交错字符串,dp[i][j]表示s1中取前i个字符(即0~i - 1),s2中取前j个字符(即0~j - 1)能否交错组成s3中前i + j个字符,dp[s1.length()][s2.length()]代表的就是整个s1和整个s2能否交错组成s3,也就是本题的答案
  • dp[i][j]怎么由前面的dp推算出来?首先dp[0][0]一定满足题意(空字符串可以组成空字符串),dp[i][j]是否满足取决于以下两种情况:
    • 如果i大于0,其可以由dp[i - 1][j]是否满足、s1的第i个字符与s3的第i + j个字符是否相同决定
    • 如果j大于0,其可以由dp[i][j - 1]是否满足、s2的第j个字符与s3的第i + j个字符是否相同决定

代码

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n1 = s1.length();
        int n2 = s2.length();
        int n3 = s3.length();
        if (n1 + n2 != n3) {
            return false;
        }
        // dp[i][j]代表s1的前i个元素与s2的前j个元素能否组成s3的前i + j个字符
        boolean[][] dp = new boolean[n1 + 1][n2 + 1];
        dp[0][0] = true;
        for (int i = 0; i <= n1; i++) {
            for (int j = 0; j <= n2; j++) {
                if (i > 0 && dp[i - 1][j]) {
                    dp[i][j] = dp[i][j] || s1.charAt(i - 1) == s3.charAt(i + j - 1);
                }
                if (j > 0 && dp[i][j - 1]) {
                    dp[i][j] = dp[i][j] || s2.charAt(j - 1) == s3.charAt(i + j - 1);
                }
            }
        }
        return dp[n1][n2];
    }
}

关键点

  • 动态规划的思想
  • 注意边界问题
  • 当dp[i][j]既能由i - 1又能由j - 1决定时,只要其中一个满足交错字符串dp[i][j]就满足

https://www.xamrdz.com/lan/5cm1896592.html

相关文章: