给定2个字符串,判断是否能够通过重排列这2个字符串而产生另外一个字符串

RT,给定字符串s1,s2判断能否通过重排列 s1 s2从而产生s3.注意s1 s2中字符的相对顺序不能变。

如:

  s1 = abc

      s2 = def

      s3 = abcdef   return true

      s3 = adefbc   return true

      s3 = aefdbc   return false

思路:

1.递归,很简单的思路,代码如下:

    bool Can(string s1, string s2, string s3) { 
        if (s3.size() != s1.size() + s2.size())
            return false;
        if (s1.size() == 0 && s2 == s3 )
            return true;
        if (s2.size() == 0 && s1 == s3)
            return true;
        if (s1[0] == s3[0]) {
            if(isInterleave(s1.substr(1, s1.size() - 1),s2, s3.substr(1, s3.size() - 1)))
                return true;
        }
        if (s2[0] == s3[0]) {
            if(isInterleave(s1,s2.substr(1, s2.size() - 1), s3.substr(1, s3.size() - 1)))
                return true;
        }
        return false;
    }

  递归的思路类似穷举,分析一下复杂度?在没有大量重复字符的时候,递归的复杂度其实还可以,但如果有大量重复字符,这个时间复杂度就难以接受了,有木有更简单的?

2.动态规划,我的理解,递归是一种不保存历史记录的动态规划,如果我们将现场保存,那么递归很容易转化为动态规划。

    bool can(string s1, string s2, string s3) {   
        if (s3.size() != s1.size() + s2.size())
            return false;
        if (s1.size() == 0) {
            if (s2 == s3)
                return true;
            else
                return false;
        }
        if (s2.size() == 0 ) {
            if (s1 == s3)
                return true;
            else
                return false;
        }
        vector<vector<bool> > dp;
        dp.resize(s1.size() + 1);
        for (int i = 0; i <= s1.size(); ++i) {
            dp[i].resize(s2.size() + 1, false);
            for (int j = 0; j <= s2.size(); ++j) {
                if (i == 0 && j == 0)
                    dp[i][j] = true;
                else if (i == 0) {
                    if (s3[i + j - 1] == s2[j - 1] && dp[i][j - 1])
                        dp[i][j] = true;
                    
                } else if (j == 0) {
                    if (s3[i + j - 1] == s1[i - 1] && dp[i - 1][j])
                        dp[i][j] = true;
                    
                } 
                else {
                    if (s3[i + j - 1] == s2[j - 1] && dp[i][j - 1])
                        dp[i][j] = true;
                    if (s3[i + j - 1] == s1[i - 1] && dp[i - 1][j])
                        dp[i][j] = true;
                }
                    
            }
        }
        return dp[s1.size()][s2.size()];
        
    }

  代码其实写得很罗嗦,基本思想是用一张表记录历史状态,没加入一个新的元素,就可以获取历史计算结果进行参考。空间复杂度为O(N^2)

  其实可以进一步缩小空间复杂度的。

posted @ 2012-12-29 14:32  David Luo  阅读(706)  评论(0编辑  收藏  举报