Leetcode 131 Palindrome Partitioning 回文分割

来源:互联网 发布:用友软件客服 编辑:程序博客网 时间:2024/06/06 03:57

原题地址

https://leetcode.com/problems/palindrome-partitioning/

题目描述

Given a string s, partition s such that every substring of the partition is a palindrome.
给出一个字符串s,对s进行分割,使得每一个子串都是一个回文串。

Return all possible palindrome partitioning of s.
返回s所有可能的回文分割。

For example, given s = “aab”,
例如,给出s = “aab”

Return
返回

[    ["aa","b"],    ["a","a","b"]]

解题思路

动态规划,先判定某子串s[i][j]是否为回文串。第二部根据这个结果来构造回文分割结果。

判定是否为回文串:/* isPalindrome[i][j]表示i,j之间的字符串是否是一个回文串  * 对于s来说,如果s[i]==s[j]且isPalindrome[i+1][j-1]==true,则isPalindrome[i][j]=true */构造回文分割结果 /* 将s[start]-s[end]分为s[start]-s[i]和s[i+1]-s[end]两部分  * 1.如果s[start]-s[i]是一个回文串,那么获取s[i+1]-s[end]的partition结果集tmp  *   tmp中的每一个结果都把s[start]-s[i]加进去就是s[start]-s[end]的partition结果集的一个解  * 2.如果s[start]-s[i]不是回文串,那么这种分割情况下没有可行解  * 3.另外,如果s[start]-s[i]是回文串,但是s[i+1]-s[end]的partition结果集为空 *    则说明此种分割情况没有可行解*/

详见代码

代码 cpp

class Solution {public:    /**     * 把字符串s进行分解,每个子串都是回文串     */    vector<vector<string> > partition(string s) {        int len = s.size();        /* isPalindrome[i][j]表示i,j之间的字符串是否是一个回文串          * 对于s来说,如果s[i]==s[j]且isPalindrome[i+1][j-1]==true,则isPalindrome[i][j]=true */        vector<vector<bool> > isPalindrome = vector<vector<bool> >(len, vector<bool>(len, false));        /* 计算并记录子串是否为回文串  */        // 单字符肯定是回文串        for (int i = 0; i < len; ++i) isPalindrome[i][i] = true;         // 计算并记录长度为2的子串是否为回文串        for (int i = 0; i < len - 1; ++i) isPalindrome[i][i + 1] = s[i] == s[i + 1];         // 计算并记录长度为3-s.size()的子串是否为回文串        for (int i = 2; i <= len; ++i)            for (int j = 0; j < len - i; ++j)                isPalindrome[j][j + i] = s[j] == s[j + i] && isPalindrome[j + 1][j + i - 1];        /* store用于存储子串的partition结果  */        vector<vector<vector<vector<string> > > > store                 = vector<vector<vector<vector<string> > > >(len, vector<vector<vector<string> > >(len));        /* done用于标记一个子串是否已经求得partition结果 */        vector<vector<bool> > done = vector<vector<bool> >(len, vector<bool>(len, false));        /* 计算s的0-s.size()-1之间(即字符串s)的partition结果 */        return subPartition(s, 0, len - 1, isPalindrome, store, done);    }private:    /**     * 计算字符串s的子串s[start]-s[end]的partition结果     * partition的结果中,每个子串都是回文串     * @param s 字符串     * @param start 子串的起始位置(包含)     * @param end 子串的结束位置(包含)     * @param isPalindrome 记录子串是否为回文串的二维数组     * @param store 用于记录已经求得的partitiion结果     * @param done 用于标记是否已求得partition结果     * @return 字符串s的子串s[start]-s[end]的partition操作的结果     */    vector<vector<string> > subPartition(string &s, int start, int end, vector<vector<bool> > &isPalindrome,            vector<vector<vector<vector<string> > > > &store, vector<vector<bool> > &done) {        /* 操作结果集 */        vector<vector<string> > ret;        if (start > end) return ret; // 验证数据有效性,start>end,直接返回空集        if (done[start][end]) return store[start][end]; // 如果已经求过,直接返回存储好的记录        /* 第一次求s[start]-s[end]的partition结果 */        for (int i = start; i < end; ++i) {            /* 将s[start]-s[end]分为s[start]-s[i]和s[i+1]-s[end]两部分             * 1.如果s[start]-s[i]是一个回文串,那么获取s[i+1]-s[end]的partition结果集tmp             *   tmp中的每一个结果都把s[start]-s[i]加进去就是s[start]-s[end]的partition结果集的一个解             * 2.如果s[start]-s[i]不是回文串,那么这种分割情况下没有可行解             * 3.另外,如果s[start]-s[i]是回文串,但是s[i+1]-s[end]的partition结果集为空             *   则说明此种分割情况没有可行解*/            if (isPalindrome[start][i]) { // 仅当s[start][i]是回文串时才有可能有解                // 获取后面子串的partition结果                vector<vector<string> > tmp = subPartition(s, i + 1, end, isPalindrome, store, done);                string tmpStr = s.substr(start, i - start + 1);                // 遍历后面子串的partition结果,添加s[start]-s[i]之后添加到结果集中                for (int j = 0; j < tmp.size(); ++j) {                     vector<string> tmpVec;                    tmpVec.push_back(tmpStr);                    tmpVec.insert(tmpVec.end(), tmp[j].begin(), tmp[j].end());                    ret.push_back(tmpVec);                }            }        }        /* 特殊情况,判断整个字符串是否是回文串,如果是则加入结果集中 */        if (isPalindrome[start][end]) {            vector<string> tmp;            tmp.push_back(s.substr(start, end - start + 1));            ret.push_back(tmp);        }        /* 修改是否已求解的标志为 */        done[start][end] = true;        /* 存储已经求得的partition结果 */        store[start][end] = ret;        return ret;    }};

完整代码https://github.com/Orange1991/leetcode/blob/master/131/cpp/main.cpp

运行情况

Status:Accept
Time:72ms

测试用例

s = aab [       [a,a,b],    [aa,b]]   s = bb  [       [b,b],    [bb]]

2015/7/23

0 0
原创粉丝点击