Leetcode 97 交错字符串 (dp)
题目描述:
题解:
普通的动态规划,dp[i][j]表示s1中前i个字符与s2中前j个字符交错形成s3前(i+j)个字符是否成立。状态转移的时候按照s3长度递增的顺序去推。
对于长度为i的情况,从s1,s2中找出与s3[i-1]相同的字符对应的位置k,然后用dp[i][i-k] = max(dp[i][i-k],dp[i-1][i-k]);
改进:用一位dp去实现,可以观察到状态转移方程是严格有序的,那么可以用一维的dp来去掉冗余的前缀。也就是滚动数组
AC代码:
普通dp
class Solution { public: // // 普通动规以及状压都试试 bool isInterleave(string s1, string s2, string s3) { int Len1 = s1.length(); int Len2 = s2.length(); int Len3 = s3.length(); if(Len1 == 0 && Len2 == 0 && Len3 == 0) return true; //cout<<Len1 <<" " <<Len2<<" " <<Len3<<endl; if(Len3 != (Len1 + Len2)) return false; int dp[Len2+Len1+10][Len1+Len2+10]; for(int i=0;i<Len2+Len1+10;i++) { for(int j=0;j<Len1+Len2+10;j++) dp[i][j] = 0; } if(s1[0] == s3[0]) dp[1][0] = 1; if(s2[0] == s3[0]) dp[0][1] = 1; // 重新处理 // len for(int i=2;i<=Len3;i++) { for(int j=1;j<=min(i,Len1);j++) if(s1[j-1] == s3[i-1]) { dp[j][i-j] = max(dp[j][i-j],dp[j-1][i-j]); } for(int j=1;j<=min(i,Len2);j++) { if(s2[j-1] == s3[i-1]) { dp[i-j][j] = max(dp[i-j][j],dp[i-j][j-1]); } } } for(int i=1;i<=Len1;i++) if(dp[i][Len3-i] == 1) { //cout << i <<" " <<Len3-i ; return true; } for(int i=1;i<=Len2;i++) if(dp[Len3-i][i] == 1) { // cout << Len3-i <<" " <<i; return true; } return false; } };