回文字符串及其变种

回文partition一般有以下几种情况:

1. 求所有的partition结果。这个一般用DFS来解。

2. 最后结果是一个整数,比如Palindrome Partitioning II。这个用DP来解

3. 最后求一个结果,比如最小切法。这个用DP+backtrack来解
4. 最长回文子串
 
问题1:求所有的回文partition结果,用简单的DFS就可以求出。
    bool isPalin(string &s,int l,int r)
    {
        while(l<r)
        {
            if(s[l]!=s[r])
                return false;
            l++;
            r--;
        }
        return true;
    }
    vector<vector<string>> partition(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        //DFS
        vector<vector<string>> res;
        if(s.empty())
            return res;
            
        vector<string> path;
        dfs(s,0,path,res);
        return res;
    }
    
    void dfs(string& s,int curpos,vector<string>& path,vector<vector<string>>& res)
    {
        if(curpos==s.size())
        {
            res.push_back(path);
            return;
        }
        
        for(int i=curpos;i<s.size();i++)
        {
            if(isPalin(s,curpos,i))
            {
                path.push_back(s.substr(curpos,i-curpos+1));
                dfs(s,i+1,path,res);
                path.pop_back();
            }
        }
    }

 ---改进版,用一个二维数组预处理子串是否回文,避免上面解法重复计算子串回文。

    vector<vector<string>> partition(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<vector<string>> res;
        if(s.empty())
            return res;
            
        int n = s.size();
            
        vector<vector<bool>> palin;
        for(int i=0;i<n;i++)
            palin.push_back(vector<bool>(n));
            
        for(int i=0;i<n;i++)
            palin[i][i] = true;
            
        for(int i=n-2;i>=0;i--) //注意:这里从i大的开始,从0开始时错误的,因为例如计算palin[0][5]需要palin[1][4],而palin[1][4]此时是未初始化的。
        {
               if(s[i]==s[i+1])
                   palin[i][i+1] = true;
               else palin[i][i+1] = false;
         
            for(int j=i+2;j<n;j++)
            {
                if(palin[i+1][j-1]&&s[i]==s[j])
                    palin[i][j] = true;
                else palin[i][j] = false;
            }
        }
        vector<string> path;
        dfs(0,s,path,palin,res);
        return res;
        
    }
    
    void dfs(int pos,string& s,vector<string>& path,vector<vector<bool>>& palin,vector<vector<string>>& res)
    {
        if(pos==s.size())
        {
            res.push_back(path);
            return;
        }
        
        for(int i=pos;i<s.size();i++)
        {
            if(palin[pos][i])
            {
                path.push_back(s.substr(pos,i-pos+1));
                dfs(i+1,s,path,palin,res);
                path.pop_back();
            }
                
        }
    }

  

问题2:求回文最小partition个数。---DP求解

posted @ 2013-09-20 23:18  summer_zhou  阅读(197)  评论(0编辑  收藏  举报