• LeetCode 97. 交错字符串


    题目链接

    97. 交错字符串

    题目分析

    字符串题目,一般不考虑暴力解法,因为极有可能会出现超时的情况(主要是重复搜索次数太多
    这个题很明显的就是需要我们使用动态规划去做,一开始我自己也懵逼了,三串的DP?难不成要一个三维状态数组吗,但是仔细分析了一下好像其实并不是的。
    因为我们s1的长度加s2的长度必定要等于s3的长度才有可能构成交错字符串,所以我们可以利用这里的关系去把三位状态数组压缩成二维。

    • dp[i][j]代表的是s1的第i-1个字符和s2的第j-1个字符匹配到s3的第i+j-1个字符的地方是否匹配

    那么我们把状态定下来之后,就是找对应的转移方程了,其转移也是非常的容易理解,这里要从上往下一个一个判断,因为存在包含关系。

    • 如果s1的当前位字符和s2的字符相等,并且s1的字符等于s3的字符,那么我们需要去判断要使用哪一个才能使得交错字符串成立,所以dp[i][j] = dp[i-1][j] || dp[i][j-1];
    • 如果s1的字符等于s3的字符,那么很明显就是要s1往前挪一步,所以dp[i][j] = dp[i-1][j];
    • s2字符相等的情况和第二点一样。

    那么我们还需要base cases,因为有可能单独s1或者s2都能匹配s3,所以我们要单独把另外一个字符串为空串的情况拿出来分析。

    总的来说这个题的状态转移和其他的字符串匹配很相似,也很容易就写出来了。

    代码实现

    class Solution {
        public boolean isInterleave(String s1, String s2, String s3) {
            if(s1.length() + s2.length() != s3.length()){
                return false;
            }
            boolean[][] dp = new boolean[s1.length()+1][s2.length()+1];
            dp[0][0] = true;
            for(int i = 0; i < s1.length(); i++){
                if(s1.charAt(i) == s3.charAt(i)){
                    dp[i+1][0] = dp[i][0];
                }
            }
            for(int i = 0; i < s2.length(); i++){
                if(s2.charAt(i) == s3.charAt(i)){
                    dp[0][i+1] =  dp[0][i];
                }
            }
            for(int i = 1; i < dp.length; i++){
                for(int j = 1; j < dp[i].length; j++){
                    if(s1.charAt(i-1) == s2.charAt(j-1) &&  s1.charAt(i-1) == s3.charAt(i+j-1)){
                        dp[i][j] = dp[i-1][j] || dp[i][j-1];
                    }else if(s1.charAt(i-1) == s3.charAt(i+j-1)){
                        dp[i][j] = dp[i-1][j];
                    }else if(s2.charAt(j-1) == s3.charAt(i+j-1)){
                        dp[i][j] = dp[i][j-1];
                    }
                }
            }
            return dp[dp.length-1][dp[0].length-1];
        }
    }
    

    总结

    DP还是得靠自己慢慢摸索才能提升。

  • 相关阅读:
    【BZOJ 1185】 凸包+旋转卡壳
    【BZOJ 2829】 2829: 信用卡凸包 (凸包)
    【BZOJ 1045】 1045: [HAOI2008] 糖果传递
    【BZOJ 2453|bzoj 2120】 2453: 维护队列 (分块+二分)
    【BZOJ 3343 】 分块
    【BZOJ 1069】 凸包+旋转卡壳
    【NOIP 2016 总结】
    【无聊放个模板系列】洛谷 负环 模板
    【无聊放个模板系列】BZOJ 3172 (AC自动机)
    【无聊放个模板系列】HDU 3506 (四边形不等式优化DP-经典石子合并问题[环形])
  • 原文地址:https://www.cnblogs.com/ZJPaang/p/13334689.html
Copyright © 2020-2023  润新知