一)交错字符串:
97. 交错字符串 - 力扣(LeetCode)
一)确定一个状态标识:
如果我选择s1的一段区间,再进行选择s2得一段区间那么s3这个字符串的长度就已经固定了
预处理:在s1字符串s2字符串和s3字符串前面加上一个虚拟字符,让下标从1开始进行计数
如果要是从1号位置开始进行计数的话会变得十分方便
s1=" "+s1
s2=" "+s2
s3=" "+s3
状态表示:dp[i][j]就表示s1中的[1,i]区间内的字符串以及s2[1,j]区间内的字符串能否拼接成s3的[1,i+j]区间内的字符串,如果能够拼接而成,那么里面存的值就是true,否则里面的值就是false;
二)根据状态表示推导状态转移方程:根据最后一个位置的情况来分情况进行讨论
1)如果s1的[0,i]区间和s2的[0,j]区间能够拼接成s3字符串的[0,i+j]区间,那么s3字符串的的i+j位置要么是等于s1的i字符,要么是等于s2的j字符,要么都不等于
2)如果能够拼接而成,要么等于s1的最后一个字符,要么等于s2的最后一个字符
if(s1[i]==s3[i+j])那么此时应该研究的就是s1字符串的[0,i-1]区间内的字符串和s2字符串的[0,j]区间内的字符串是否能够构成s3字符串从[0,i-1+j]的子串
if(s1[i]==s3[i+j]) dp[i][j]=dp[i-1][j]
if(s2[j]==s3[i+j]) dp[i][j]=dp[i][j-1]
三)初始化:
引入空串,在原始的dp表中新增加了一行并且新增加了一列
1)dp[0][0]表示的是第一个字符串是空串况且第二个字符串也是空串,空串拼接空串当然可以
2)现在来看dp[0][i]位置的值(i>0),如果第一个字符串为空,第二个字符串不为空,如果想拼接成第三个字符串,那么必须是对应位置的字符相等才可以,也就是第二个字符串和第三个字符串必须完全相等才可以,如果出现一个位置对应字符不相等,全部白玩
四)填表顺序+返回值:从上向下填写每一行,每一行从左向右进行编写,返回值是dp[m][n]
class Solution { public boolean isInterleave(String s1, String s2, String s3) { if(s1.length()+s2.length()!=s3.length()) return false; //1.先针对初始字符串进行预处理 s1="-"+s1; s2="-"+s2; s3="-"+s3; char[] array1=s1.toCharArray(); char[] array2=s2.toCharArray(); char[] array3=s3.toCharArray(); //2.创建一个dp表,先进行初始化 boolean[][] dp=new boolean[array1.length][array2.length]; dp[0][0]=true; for(int i=1;i<array2.length;i++){ if(array2[i]==array3[i]) dp[0][i]=true; else break; } for(int j=1;j<array1.length;j++){ if(array1[j]==array3[j]) dp[j][0]=true; else break; } //3.填表 for(int i=1;i<array1.length;i++){ for(int j=1;j<array2.length;j++){ dp[i][j]=(array1[i]==array3[i+j]&&dp[i-1][j])||(array2[j]==array3[i+j]&&dp[i][j-1]); } } //4.返回值 return dp[array1.length-1][array2.length-1]; } }