97. Interleaving String

题目:

Given s1s2s3, find whether s3 is formed by the interleaving of s1 and s2.

For example,
Given:
s1 = "aabcc",
s2 = "dbbca",

When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.

  给定字符串S1、S2、S3,判断S3是否由S1和S2交错形成。即每次从这两个字符串中的一个中取出一个字符(从前往后取),

直到两个字符串都取完,这样可以组成很多新的字符串,问s3是否属于这些新组成的字符串中的一个。

解题思路:

  采用动态规划。构造一个二维数组dp[rows+1][cols+1],rows = S1.size(),cols = S2.size(),其中dp[i][j]表示S3中前i+j个字符串是否

由S1中前i个字符串与S2中前j个字符串交错形成。

  首先初始化数组第一行和第一列。

  dp[0][0] = true;

  dp[i][0] = dp[i - 1][0] && s1[i - 1] == s3[i - 1];

  dp[0][j] = dp[0][j - 1] && s2[j - 1] == s3[j - 1];

  动态规划方程为:

  dp[i][j] = dp[i][j - 1] && s2[j - 1] == s3[i + j - 1] || dp[i - 1][j] && s1[i - 1] == s3[i + j - 1];

  也即,如果S3中前i+j-1个字符串由S1中前i个字符串与S2中前j-1个字符串交错形成,并且S2中第j个字符与S3中第i+j个字符相同时,

则S3中前i+j个字符串是由S1中前i个字符串与S2中前j个字符串交错形成。同理,如果S3中前i+j-1个字符串由S1中前i-1个字符串与S2中

前j个字符串交错形成,并且S1中第i个字符与S3中第i+j个字符相同时,也符合条件。

代码如下:

 1 class Solution {
 2 public:
 3     bool isInterleave(string s1, string s2, string s3) {
 4         int rows = s1.size();
 5         int cols = s2.size();
 6         if (rows + cols != s3.size())
 7             return false;
 8         if (rows == 0)
 9             return s2 == s3;
10         if (cols == 0)
11             return s1 == s3;
12         vector<vector<bool>> dp(rows + 1, vector<bool>(cols + 1));
13         dp[0][0] = true;
14         for (int j = 1; j <= cols; j++)
15         {
16             dp[0][j] = dp[0][j - 1] && s2[j - 1] == s3[j - 1];
17         }
18         for (int i = 1; i <= rows; i++)
19         {
20             dp[i][0] = dp[i - 1][0] && s1[i - 1] == s3[i - 1];
21         }
22         for (int i = 1; i <= rows; i++)
23         {
24             for (int j = 1; j <= cols; j++)
25             {
26                 dp[i][j] = dp[i][j - 1] && s2[j - 1] == s3[i + j - 1] || dp[i - 1][j] && s1[i - 1] == s3[i + j - 1];
27             }
28         }
29         return dp[rows][cols];
30     }
31 };

 为了节省空间,可以将二维数组用一维数组dp[cols+1]代替。

 动态规划方程变为:

   dp[j] = dp[j-1] && s2[j-1] == s3[i+j-1] || dp[j] && s1[i-1] == s3[i+j-1];

代码如下:

 1 class Solution {
 2 public:
 3     bool isInterleave(string s1, string s2, string s3) {
 4         int rows = s1.size();
 5         int cols = s2.size();
 6         if(rows + cols != s3.size())
 7             return false;
 8         if(rows == 0)
 9             return s2 == s3;
10         if(cols == 0)
11             return s1 == s3;
12         vector<bool> dp(rows+1);
13         dp[0] = true;
14         for(int j=1;j<=cols;j++)
15         {
16             dp[j] = dp[j-1] && s2[j-1] == s3[j-1];
17         }
18         for(int i = 1;i<=rows;i++)
19         {
20             dp[0] = dp[0] && s1[i-1] == s3[i-1];
21             for(int j = 1;j<=cols;j++)
22             {
23                 dp[j] = dp[j-1] && s2[j-1] == s3[i+j-1] || dp[j] && s1[i-1] == s3[i+j-1];
24             }
25         }
26         return dp[cols];
27     }
28 };

 

posted on 2018-02-05 09:57  IT_Amateur  阅读(129)  评论(0编辑  收藏  举报

导航