(1过,调试很久)

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

示例 1:

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

示例 2:

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

关键:设dp[i][j]表示s3的前i+j个字符可以由s1的前i个字符和s2的前j个字符交织而成

看了这句提示才写出来,中途忽略了length1 + length2 != length3的条件调试了很久

    public boolean isInterleave(String s1, String s2, String s3) {
int length1 = s1.length();
int length2 = s2.length();
//s3长度可能小于s1+s2,s3.charAt(i+j-1)会溢出
int length3 = s3.length();
//设dp[i][j]表示s3的前i+j个字符可以由s1的前i个字符和s2的前j个字符交织而成
boolean[][] dp = new boolean[length1+1][length2+1];
//初始化
if (length1 + length2 != length3)
return false;
dp[0][0] = true;
for (int i=1;i<=length1;i++) {
if (dp[i - 1][0] && s1.charAt(i-1) == s3.charAt(i-1))
dp[i][0] = true;
else
dp[i][0] = false;
}
for (int i=1;i<=length2;i++) {
if (dp[0][i-1] && s2.charAt(i-1) == s3.charAt(i-1))
dp[0][i] = true;
else
dp[0][i] = false;
}
for (int i=1;i<=length1;i++) {
for (int j=1;j<=length2;j++) {
if ((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))) {
dp[i][j] = true;
} else {
dp[i][j] = false;
}
}
}
return dp[length1][length2];
}

参考:

s3是由s1和s2交织生成的,意味着s3由s1和s2组成,在s3中s1和s2字符的顺序是不能变化的,和子序列题型类似,这种题我们一般是用动态规划来解。

    1. 设dp[i][j]表示s3的前i+j个字符可以由s1的前i个字符和s2的前j个字符交织而成。
  1. 状态转移方程:有两种情况
    • 第一个状态转移方程:
      dp[i][j]= {(dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)}
      dp[i-1][j]表示若s3的前i+j-1个字符能够由s1前i-1个字符和s2的前j个字符交织而成,那么只需要s1的第i个字符与s3的第i+j个字符相等(charAt索引从0开始),那么dp[i][j]=true;
    • 第二个状态转移方程:
      dp[i][j]= {(dp[i][j-1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)}
      dp[i-1][j]表示若s3的前i+j-1个字符能够由s1前i个字符和s2的前j-1个字符交织而成,那么只需要s2的第j个字符与s3的第i+j个字符相等(charAt索引从0开始),那么dp[i][j]=true;
链接:https://www.nowcoder.com/questionTerminal/4d0f94617e454e2da23e660cded4d9e8
来源:牛客网 public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int len1 = s1.length();
        int len2 = s2.length();
        int len3 = s3.length();
       
        if(len1+len2 !=len3){
          return false;
        }
         
        char[] chs1 = s1.toCharArray();
        char[] chs2 = s2.toCharArray();
        char[] chs3 = s3.toCharArray();
         
        //dp[i][j]代表 chs1[0...i]  chs2[0...j]能否顺序匹配chs3[i+j]
        boolean[][] dp = new boolean[len1+1][len2+1];
        //初始化 s1中取0个字符 s2中取0个字符 匹配s3从0开始的0个字符 肯定匹配true
        dp[0][0] = true;
         
        //s1中取0个s2中取i个 去和s3中0+i 个匹配
        for(int i = 1 ; i < len2 + 1; i ++ ){
          dp[0][i] = dp[0][i-1] && chs2[i-1] == chs3[i-1];
        }
        //s2中取0个s1中取i个 去和s3中0+i 个匹配
        for(int i = 1 ; i < len1 + 1; i ++ ){
          dp[i][0] = dp[i-1][0] && chs1[i-1] == chs3[i-1];
        }
         
        for(int i = 1 ; i < len1+1 ; i ++ ){
          for(int j = 1 ; j < len2+1 ; j ++ ){
            dp[i][j] = dp[i-1][j] && (chs3[i+j-1] == chs1[i-1])
                || dp[i][j-1] && (chs3[i+j-1] == chs2[j-1]);
          }
        }
         
        return dp[len1][len2];
    }
}

【leetcode-97 动态规划】 交错字符串的更多相关文章

  1. Java实现 LeetCode 97 交错字符串

    97. 交错字符串 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的. 示例 1: 输入: s1 = "aabcc", s2 = " ...

  2. Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings)

    Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings) 给定两个字符串s1, s2,找到 ...

  3. Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)

    Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理) 题目描述 一条报文包含字母A-Z,使用下面的字母-数字映射进行解码 'A' -> 1 'B' -> 2 ...

  4. leetcode笔记 动态规划在字符串匹配中的应用

    目录 leetcode笔记 动态规划在字符串匹配中的应用 0 参考文献 1. [10. Regular Expression Matching] 1.1 题目 1.2 思路 && 解题 ...

  5. Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings)

    Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings) 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子 ...

  6. Leetcode之动态规划(DP)专题-474. 一和零(Ones and Zeroes)

    Leetcode之动态规划(DP)专题-474. 一和零(Ones and Zeroes) 在计算机界中,我们总是追求用有限的资源获取最大的收益. 现在,假设你分别支配着 m 个 0 和 n 个 1. ...

  7. Leetcode之动态规划(DP)专题-392. 判断子序列(Is Subsequence)

    Leetcode之动态规划(DP)专题-392. 判断子序列(Is Subsequence) 给定字符串 s 和 t ,判断 s 是否为 t 的子序列. 你可以认为 s 和 t 中仅包含英文小写字母. ...

  8. Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance)

    Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance) 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可 ...

  9. Leetcode之动态规划(DP)专题-详解983. 最低票价(Minimum Cost For Tickets)

    Leetcode之动态规划(DP)专题-983. 最低票价(Minimum Cost For Tickets) 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行.在接下来的一年里,你要旅行的 ...

  10. Leetcode(8)字符串转换整数

    Leetcode(8)字符串转换整数 [题目表述]: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我 ...

随机推荐

  1. 一起学Makefile(三)

    makefile工具箱 complicated项目的构建 文件结构如下: 文件内容如下: 项目依赖关系: gcc编译出可执行文件的过程包含了两个过程,编译和链接. makefile如下: 运行结果:

  2. 获取shell脚本自身所在目录

    解决了使用ln -s target linkName创造软链接无法正确取到真实脚本的问题. #!/bin/bash SOURCE="$0" while [ -h "$SO ...

  3. Gradle系列教程之依赖管理

    这一章我将介绍Gradle对依赖管理的强大支持,学习依赖分组和定位不同类型仓库.依赖管理看起来很容易,但是当出现依赖解析冲突时就会很棘手,复杂的依赖关系可能导致构建中依赖一个库的多个版本.Gradle ...

  4. DataGrip:Error encountered when performing Introspect schema xxx 错误的解决方法

    datagrip的问题,转载自: https://www.cnblogs.com/geb515/p/7995249.html 把Introspect using JDBC _metadata打上勾 然 ...

  5. [转]js对象中取属性值(.)和[ ]的区别

    原文地址:https://www.jianshu.com/p/6a76530e4f8f 今天在写js的过程中遇到这么一个问题,取一个对象的属性值,通过obj.keys怎么都取不出来,但是用obj[ke ...

  6. 使用python脚本批量设置nginx站点的rewrite规则

    一般情况下,配置rewrite重写规则使用shell脚本即可: 把url拼凑成1,2文件中中的格式,运行 chongxie.sh 即可生成我们需要的rewrite规则 [root@web01:/opt ...

  7. Java12新特性 -- 可中断的 G1 Mixed GC

    G1是一个垃圾收集器,设计用于具有大量内存的多处理器机器.由于它提高了性能效率,G1垃圾收集器最终将取代CMS垃圾收集器. 该垃圾收集器设计的主要目标之一是满足用户设置的预期的 JVM 停顿时间. G ...

  8. 【jmeter】使用jmeter进行测试-示例

    介绍 jmeter主要用于负载测试,详细信息可以参见Google. 这里使用一个简单的示例,来介绍jmeter的使用. 涉及的功能点包括: HTTP HEADER配置 HTTP Request配置 J ...

  9. Operation之算数&聚合操作符

    toArray 该操作符先把一个序列转成一个数组, 并作为一个单一的事件发送, 然后结束 Observable.of(1,2,3,4) .toArray() .subscribe(onNext: { ...

  10. advanceInstaller安装文件的ICON

    修改以下配置 点击icon图标位置可重新选择