LeetCode 97交错字符串(动态规划)
微信搜一搜:bigsai
大家都在關注的刷題、學習數據結構和算法寶藏項目
關注回復進群即可加入力扣打卡群,歡迎劃水。近期打卡:
LeetCode 92反轉鏈表Ⅱ&93復制ip地址&94二叉樹的中序遍歷
LeetCode 96不同的二叉搜索樹&95不同的二叉搜索樹Ⅱ
交錯字符串
給定三個字符串 s1、s2、s3,請你幫忙驗證 s3 是否是由 s1 和 s2 交錯 組成的。
兩個字符串 s 和 t 交錯 的定義與過程如下,其中每個字符串都會被分割成若干 非空 子字符串:
s = s1 + s2 + ... + sn t = t1 + t2 + ... + tm |n - m| <= 1 交錯 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ... 提示:a + b 意味著字符串 a 和 b 連接。示例 1:
示例 2:
輸入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" 輸出:false示例 3:
輸入:s1 = "", s2 = "", s3 = "" 輸出:true提示:
0 <= s1.length, s2.length <= 100 0 <= s3.length <= 200 s1、s2、和 s3 都由小寫英文字母組成分析
這種題一看的話就是一個動態規劃類的問題,動態規劃類的問題的難點就是找到狀態轉移方程,另一個重要點就是正確完成初始化。
先看正常情況的狀態轉移方程,對于這道題要求的就是問s3能否被s1,s2所連接。如果能夠被連接,也就是s3的從前到后任意部分都能由s1和s2拼接而成。我們需要保證的就是從前向后s3的每一個長度都能被成功匹配。
分析s3[0-i]是否能夠被匹配有下面幾種情況:
- 完全由s1匹配,最后一位開始到前面每一位都和s3相等。
- 完全由s2匹配,最后一位開始到前面每一位都和s3相等。
- s1部分和s2部分匹配,但是一定有s1選定長度的最后一位或者s2選定長度的最后一位與s3[i]相等(否則無法正確匹配)。并且s1選定長度+s2選定長度=s3選定長度。
知道這些關系,我們不妨設一個dp[s1.length()+1][s2.length()+1] ,dp[i+1][j+1]表示s1的[0,i]和s2的[0,j]能否匹配s3的[0,i+j+1]匹配(這里的0號留給空而不是編號上0的第一位)。所以狀態轉移方程為:
if(ch1[i]==ch3[i+j+1])//s1串的最后一個和s3匹配 {dp[i+1][j+1]=dp[i][j+1];//去掉當前字符前面的結果 } if(!dp[i+1][j+1]&&ch2[j]==ch3[i+j+1])//s2串的最后一個和s3匹配 {dp[i+1][j+1]=dp[i+1][j]; }當然,具體的實現上,我們需要枚舉兩個字符串進行求dp,還要進行正確的初始話,因為我們約定這里為null對應的dp為0,比如s1是abc s2是 e s3是abce,那么最終的匹配 dp[3][0]表示s1三個,s2零個匹配。而dp[3][1]才是表示s1三個,s2一個進行匹配。
而在初始話過程除了dp[0][0]=true之外,還需要處理s1不使用和s2不使用的匹配情況(即dp[0][i]和dp[i][0]).
當然,在具體實現上可以剪枝優化,比如dp[i][]一定有其中一個多個為true,否則就不可能成功匹配。
具體的代碼為:
public static boolean isInterleave(String s1, String s2, String s3) {if(s1.length()+s2.length()!=s3.length())return false;if(s3.equals(""))return true;char ch1[]=s1.toCharArray();char ch2[]=s2.toCharArray();char ch3[]=s3.toCharArray();boolean dp[][]=new boolean[s1.length()+1][s2.length()+1];dp[0][0]=true;//兩個空串為truefor(int i=0;i<s1.length();i++){if(ch1[i]==ch3[i])dp[i+1][0]=true;//注意這里用i+1 else {break;}}for(int j=0;j<s2.length();j++){if(ch2[j]==ch3[j])dp[0][j+1]=true;else {break;}}for(int i=0;i<s1.length();i++){char c1=ch1[i];boolean jud=dp[i+1][0];for(int j=0;j<s2.length();j++){if(c1==ch3[i+j+1]){dp[i+1][j+1]=dp[i][j+1];}if(!dp[i+1][j+1]&&ch2[j]==ch3[i+j+1]){dp[i+1][j+1]=dp[i+1][j];}if(dp[i+1][j+1])jud=true;}if(!jud)return false;}return dp[s1.length()][s2.length()]; }原創不易,bigsai請你幫兩件事幫忙一下:
star支持一下, 您的肯定是我在平臺創作的源源動力。
微信搜索「bigsai」,關注我的公眾號,不僅免費送你電子書,我還會第一時間在公眾號分享知識技術。加我還可拉你進力扣打卡群一起打卡LeetCode。
記得關注、咱們下次再見!
總結
以上是生活随笔為你收集整理的LeetCode 97交错字符串(动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 96不同的二叉搜索树9
- 下一篇: LeetCode 98验证二叉搜素树(中