每日一题——交错字符串

菜鸡每日一题系列打卡97

每天一道算法题目 

小伙伴们一起留言打卡

坚持就是胜利,我们一起努力!

题目描述(引自LeetCode)

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

示例 1:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true
示例 2:
输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false

题目分析

这是一道典型的回溯的题目,也是一道典型的动态规划的题目。

为了给小伙伴们提供更多思路,菜鸡将采用上述两种方式进行实现,但由于回溯法的时间复杂度太高,导致leetcode测试集会出现超时的情况,虽然可以用记忆化回溯的方式进行优化,但并没有实际降低其时间复杂度,因此,菜鸡推荐采用效果更好的动态规划解法。

话不多说,上代码!

代码实现

// 回溯法
public class Solution {


    public boolean isInterleave(String s1, String s2, String s3) {
        return backTrace(s1, 0, s2, 0, "", s3);
    }


    public boolean backTrace(String s1, int i, String s2, int j, String tmp, String s3) {
        if (tmp.equals(s3) && i == s1.length() && j == s2.length()) return true;
        boolean flag = false;
        if (i < s1.length()) flag |= backTrace(s1, i + 1, s2, j, tmp + s1.charAt(i), s3);
        if (j < s2.length()) flag |= backTrace(s1, i, s2, j + 1, tmp + s2.charAt(j), s3);
        return flag;
    }


}
// 动态规划
class Solution {


    public boolean isInterleave(String s1, String s2, String s3) {
        // 特殊情况处理
        if (s1 == null || s2 == null || s3 == null || s3.length() != s1.length() + s2.length()) return false;
        // 节省dp数组的空间开销
        if (s1.length() < s2.length()) return isInterleave(s2, s1, s3);
        boolean dp[] = new boolean[s2.length() + 1];
        // 计算dp数组
        for (int i = 0; i <= s1.length(); i++) {
            for (int j = 0; j <= s2.length(); j++) {
                if (i == 0 && j == 0) dp[j] = true;
                else if (i == 0) dp[j] = dp[j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1);
                else if (j == 0) dp[j] = dp[j] && s1.charAt(i - 1) == s3.charAt(i + j - 1);
                else dp[j] = (dp[j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) || (dp[j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1));
            }
        }
        // 返回结果
        return dp[s2.length()];
    }


}

代码分析

对代码进行分析,不妨设字符串s1的长度为m,字符串s2的长度为n,则有:

  • 回溯法:时间复杂度为O(2^(m + n)),空间复杂度为O(m + n)。

  • 动态规划:双重for循环的时间复杂度为O(mn),空间复杂度为O(min(m, n))。

执行结果

每日一题——交错字符串_第1张图片

回溯法的执行结果

每日一题——交错字符串_第2张图片

动态规划的执行结果

学习 | 工作 | 分享

????长按关注“有理想的菜鸡

只有你想不到,没有你学不到

你可能感兴趣的:(每日一题——交错字符串)