• [LeetCode] 97. 交错字符串


    题目链接 : https://leetcode-cn.com/problems/interleaving-string/

    题目描述:

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

    示例:

    示例 1:

    输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
    输出: true
    

    示例 2:

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

    思路:

    思路一:动态规划

    • 自底向上

      动态方程:

      dp[i][j]表示s1的前i元素和s2j元素是否交错组成s3i+j元素

      所以有动态方程:

      dp[i][j] = (dp[i-1][j] && s3[i+j-1] == s1[i-1]) || (dp[i][j-1] && s2[j-1] == s3[i+j-1])

      注意:针对第一行,第一列要单独考虑

    • 自顶向下

    思路二: BFS

    代码:

    class Solution:
        def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
            n1 = len(s1)
            n2 = len(s2)
            n3 = len(s3)
            if n1 + n2 != n3: return False
    
            dp = [[False] * (n2 + 1) for _ in range(n1 + 1)]
    
            dp[0][0] = True
            # 第一行
            for j in range(1, n2 + 1):
                dp[0][j] = (dp[0][j - 1] and s2[j - 1] == s3[j - 1])
    
            # 第一列
            for i in range(1, n1 + 1):
                dp[i][0] = (dp[i - 1][0] and s1[i - 1] == s3[i - 1])
            # print(dp)
    
            for i in range(1, n1 + 1):
                for j in range(1, n2 + 1):
                    dp[i][j] = (dp[i - 1][j] and s1[i - 1] == s3[i + j - 1]) or (
                            dp[i][j - 1] and s2[j - 1] == s3[i + j - 1])
            # print(dp)
            return dp[-1][-1]
    

    java

    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[][] dp = new boolean[n1 + 1][n2 + 1];
            dp[0][0] = true;
            // 第一行
            for (int j = 1; j <= n2; j++) dp[0][j] = (dp[0][j - 1] && s2.charAt(j - 1) == s3.charAt(j - 1));
            // 第一列
            for (int i = 1; i <= n1; i++) dp[i][0] = (dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1));
            for (int i = 1; i <= n1; i++) {
                for (int j = 1; j <= n2; j++) {
                    dp[i][j] = (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1));
                }
            }
            return dp[n1][n2]; 
        }
    }
    

    自顶向下

    class Solution:
        def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
            import functools
            n1 = len(s1)
            n2 = len(s2)
            n3 = len(s3)
            @functools.lru_cache(None)
            def helper(i, j, k):
                if i == n1 and j == n2 and k == n3:
                    return True
                if k < n3:
                    if i < n1 and s1[i] == s3[k] and helper(i+1, j, k+1):
                        return True
                    if j < n2 and s2[j] == s3[k] and helper(i, j+1, k+1):
                        return True
                return False
            return helper(0,0,0)
    

    思路二:

    class Solution:
        def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
            from collections import deque
            n1 = len(s1)
            n2 = len(s2)
            n3 = len(s3)
            if n1 + n2 != n3: return False
    
            queue = deque()
            queue.appendleft((0, 0))
            visited = set()
            while queue:
                i, j = queue.pop()
                if i == n1 and j == n2:
                    return True
                if i < n1 and s1[i] == s3[i + j] and (i + 1, j) not in visited:
                    visited.add((i + 1, j))
                    queue.appendleft((i + 1, j))
                if j < n2 and s2[j] == s3[i + j] and (i, j + 1) not in visited:
                    visited.add((i, j + 1))
                    queue.appendleft((i, j + 1))
            return False
    

    java

    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();
                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;
        }
    }
    
  • 相关阅读:
    致21岁的自己
    nginx 入门实战
    软件测试的分类
    Springboot 使用 Jedis
    NodeJS模块、包、NPM
    NodeJS介绍
    毫秒必争,前端网页性能最佳实践--转载
    IT主要在线学习网站
    电商峰值系统架构设计--转载
    查看w3wp进程占用的内存及.NET内存泄露,死锁分析--转载
  • 原文地址:https://www.cnblogs.com/powercai/p/11066230.html
Copyright © 2020-2023  润新知