• LeetCode131:Palindrome Partitioning


    题目:

    Given a string s, partition s such that every substring of the partition is a palindrome.

    Return all possible palindrome partitioning of s.

    For example, given s = "aab",
    Return

      [
        ["aa","b"],
        ["a","a","b"]
      ]
    解题思路:
    这道题跟Word Break II这道基本一样,需要用DP+DFS解决

    这里采用DP中的自底向上实现,dp[i]表示前i个字符是否为切分为多个回文字符串。当求解dp[i]时,可利用已经求解的dp[i-1],

    dp[i-2]…dp[1],dp[0]进行求解。

    对于dp[n]的求解,我们可以将n个字符进行切分求解,分为前i个字符和后n-i个字符,i可以为(0,1,2,3,4…n-1)

    假设i为1时,可根据dp[i]和后面的n-1个字符组成的单词是否在dict中来判断dp[n],只要i(0,1,2,3,4…n-1)其中一种

    情况为真,则dp[n]为true,表示可以进行切分为多个回文字符串。

    因为本题需要重构结果,所以必须要有一个数据结构来保存每段长度的切割方案,这里我用unordered_map<int, vector<int> >进行保存,key为字符长度,vector保存该key对应的切割方案。

    如何求得unordered_map<int, vector<int> >中的值呢?那就应该利用求解dp[i]时,每当有一种切割方案使得dp[i]为true时,将其对应的切割位置存放到i对应的vector中,待之后用于结果重构。

    unordered_map<int, vector<int> >求得后,接下来是采用DFS算法进行结果重构,如代码执行结果图,当长度为3时,有一种切割方案,即在长度为2的位置进行切割,然后长度为2的切割方案又有两种0和1,长度为1时,切割方案都为0,所以采用DFS时,遍历顺序为2,0然后获得一种结果,之后回溯到2,1,因为1的切割方案为0,所以为3,1,0,又是一种结果。

    实现代码:

    #include <iostream>
    #include <vector>
    #include <iterator>
    #include <unordered_map>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    /*
    Given a string s, partition s such that every substring of the partition is a palindrome.
    
    Return all possible palindrome partitioning of s.
    
    For example, given s = "aab",
    Return
    
      [
        ["aa","b"],
        ["a","a","b"]
      ]
    */
    class Solution {
    public:
        //DP
        vector<vector<string>> partition(string s) {
            vector<vector<string>> retvec;
            if(s.size() == 0)
                return retvec;
            int len = s.size();
            vector<bool> dp(len+1, false);//前i个字符是否为回文数 
            dp[0] = true;
            unordered_map<int, vector<int>> hashtable;//对前i个字符,如果其为回文数时的切分点 
            for(int i = 1; i <= len; i++)
            {
                vector<int> tmpv;
                for(int j = 0; j < i; j++)
                {
                    if(dp[j] && isPalindrome(s.substr(j, i-j)) )
                    {
                        dp[i] = true;
                        tmpv.push_back(j);
                        
                    }
                }
                hashtable[i] = tmpv;
            }
            
            for(int k = 1; k <= len; k++)
            {
                vector<int> tvec = hashtable[k];
                cout<<k<<":";
                copy(tvec.begin(), tvec.end(), ostream_iterator<int>(cout, " "));
                cout<<endl;
            }
            vector<int> curvec;
            getResult(retvec, hashtable, s, len, curvec);
            return retvec;
             
            
        }
        bool isPalindrome(string s)
        {
            int len = s.size();
            if(len == 0)
                return false;
            for(int i = 0; i <= len/2; i++)
                if(s[i] != s[len-i-1])
                    return false;
            return true;
        }
        
        //DFS 
        void getResult(vector<vector<string>> &retvec, unordered_map<int, vector<int>> &hashtable, string &s, int len, vector<int> &curvec)
        {
            if(len == 0)
            {
                vector<string> tv;
                int start = curvec.back();
                for(int i = curvec.size()-2; i >= 0; i--)
                {
                    int c = curvec[i];
                    tv.push_back(s.substr(start, c-start));
                    start = c;               
                }
                tv.push_back(s.substr(curvec[0]));
                retvec.push_back(tv);
                return ;  
            }
            vector<int> tmpv = hashtable[len];
            vector<int>::iterator iter;
            for(iter = tmpv.begin(); iter != tmpv.end(); ++iter)
            {
                curvec.push_back(*iter);
                getResult(retvec, hashtable, s, *iter, curvec);
                curvec.pop_back();
                
            }
            
            
            
        }
    };
    
    int main(void)
    {
        string s("aab");
        Solution solution;
        vector<vector<string>> retvv = solution.partition(s);
        vector<vector<string>>::iterator iter;
        for(iter = retvv.begin(); iter != retvv.end(); ++iter)
        {
            vector<string>::iterator it;
            for(it = (*iter).begin(); it != (*iter).end(); ++it)
                cout<<*it<<" ";
            cout<<endl;
        }
        
        return 0;
    }

    运行结果:

    image

  • 相关阅读:
    00037_this关键字
    一些Perl例程(全部手打并执行过)
    告别码农生涯
    转载:直面人生的大实话
    iOS sqlite C语言操作
    linux C++ 莫名奇异的段错误(segmentation fault),无法调用其他函数
    iWatch应用开发-oc篇
    Android中的音频处理------SoundPool,MediaRecorder,MediaPlayer以及RingStone总结
    (二)用控制器controller给模型数据赋初始值
    PhoneGap开发的android项目环境搭建简单流程
  • 原文地址:https://www.cnblogs.com/mickole/p/3683271.html
Copyright © 2020-2023  润新知