[Leetcode][第97题][JAVA][交错字符串][BFS][动态规划]

239 篇文章 1 订阅
【问题描述】[中等]

在这里插入图片描述

【解答思路】
1. 动态规划

第 1 步:设计状态
f(i,j) 表示 s 1的前 i个元素和 s2 的前 j个元素是否能交错组成 s3的前 i + j 个元素

第 2 步:状态转移方程
在这里插入图片描述
p = i + j - 1 p为s3的长度

第 3 步:考虑初始化
boolean[][] f = new boolean[n + 1][m + 1];
f(0,0)=True
第 4 步:考虑输出
f[n][m];

第 5 步:考虑是否可以状态压缩

时间复杂度:O(NM) 空间复杂度:O(NM)

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n = s1.length(), m = s2.length(), t = s3.length();
//长度之和都不等,肯定无法由s1和s2交替组成s3
        if (n + m != t) {
            return false;
        }

        boolean[][] f = new boolean[n + 1][m + 1];
//边界条件:认为s1的前0个字符和s2的前0个字符,可以交替组成s3的前0个字符
        f[0][0] = true;
        for (int i = 0; i <= n; ++i) {
            for (int j = 0; j <= m; ++j) {
                int p = i + j - 1;
                if (i > 0) {
                //官方代码前面这个'f[i][j] ||'是没必要的
                    f[i][j] = f[i][j] || (f[i - 1][j] && s1.charAt(i - 1) == s3.charAt(p));
                }
                if (j > 0) {
                //如果前一步i>0时已算出f[i][j]为true,则下面的||会短路,f[i][j]直接就是true了
                    f[i][j] = f[i][j] || (f[i][j - 1] && s2.charAt(j - 1) == s3.charAt(p));
                }
            }
        }
//返回结果:s1的前n个字符和s2的前m个字符,可否交替组成s3的前n+m个字符
        return f[n][m];
    }
}




在这里插入图片描述

时间复杂度:O(NM) 空间复杂度:O(M)
在这里插入图片描述

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n = s1.length(), m = s2.length(), t = s3.length();

        if (n + m != t) {
            return false;
        }

        boolean[] f = new boolean[m + 1];

        f[0] = true;
        for (int i = 0; i <= n; ++i) {
            for (int j = 0; j <= m; ++j) {
                int p = i + j - 1;
                if (i > 0) {
                    f[j] = f[j] && s1.charAt(i - 1) == s3.charAt(p);
                }
                if (j > 0) {
                    f[j] = f[j] || (f[j - 1] && s2.charAt(j - 1) == s3.charAt(p));
                }
            }
        }

        return f[m];
    }
}


2. BFS

在这里插入图片描述

时间复杂度:O(NM) 空间复杂度:O(NM)

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;
        //判断是否已经遍历过
        boolean[][] visited = new boolean[n1 + 1][n2 + 1];
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0, 0});
        while (!queue.isEmpty()) {
            int[] tmp = queue.poll();
            /到达右下角就返回 true
            if (tmp[0] == n1 && tmp[1] == n2) return true;
            / 尝试是否能向右走
            if (tmp[0] < n1 && s1.charAt(tmp[0]) == s3.charAt(tmp[0] + tmp[1]) && !visited[tmp[0] + 1][tmp[1]]) {
                visited[tmp[0] + 1][tmp[1]] = true;
                queue.offer(new int[]{tmp[0] + 1, tmp[1]});
            }
            / 尝试是否能向下走
            if (tmp[1] < n2 && s2.charAt(tmp[1]) == s3.charAt(tmp[0] + tmp[1]) && !visited[tmp[0]][tmp[1] + 1]) {
                visited[tmp[0]][tmp[1] + 1] = true;
                queue.offer(new int[]{tmp[0], tmp[1] + 1});
            }

        }
        return false;
    }
}




【总结】
1. 动态规划流程

第 1 步:设计状态
第 2 步:状态转移方程
第 3 步:考虑初始化
第 4 步:考虑输出
第 5 步:考虑是否可以状态压缩

2. BFS DFS 遍历好助手

转载链接:https://leetcode-cn.com/problems/interleaving-string/solution/jiao-cuo-zi-fu-chuan-by-leetcode-solution/
参考链接:https://leetcode-cn.com/problems/interleaving-string/solution/dong-tai-gui-hua-he-bfs-by-powcai/

参考链接:https://leetcode-cn.com/problems/interleaving-string/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-2-9/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值