您的位置:首页 > 其它

[Leetcode] Palindrome Partitioning

2014-10-13 12:49 190 查看
题目:

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"]
]


思路一:Brute Force解法需要判断所有子字符串是否为回文,这样同一子字符串可能被判断多次,因此考虑到用动态规划。利用一个矩阵记录信息,A[i][j]表示S[i...j]是否为回文。这样下一次需要判断时可以直接从矩阵中获得信息。

class Solution {
public:
    vector<string> trace;
    
    bool isPalindrome(const string& s) {
        for (int i = 0; i < s.length() / 2; ++i) {
            if (s[i] != s[s.length() - 1 - i]) return false;
        }
        return true;
    }
    
    void dfs(const vector<vector<bool>>& record, const string& s, 
            int pos, vector<vector<string>>& result) {
        if (pos == (int)s.size()) {
            result.push_back(trace);
            return;
        }
        for (int i = pos; i < (int)s.size(); ++i) {
            if (record[pos][i]) {
                trace.push_back(s.substr(pos, i - pos + 1));
                dfs(record, s, i + 1, result);
                trace.pop_back();
            }
        }
    }
    
    vector<vector<string>> partition(string s) {
        vector<vector<bool>> record(s.size(), vector<bool>(s.size(), false));
        // calculate the status matrix
        for (int i = 0; i < (int)s.size(); ++i) {
            for (int j = i; j < (int)s.size(); ++j) {
                record[i][j] = isPalindrome(s.substr(i, j - i + 1));
            }
        }
        // get all the combinations
        vector<vector<string>> result;
        dfs(record, s, 0, result);
        return result;
    }
};


思路二(优化):在思路一的基础上,在计算某个子字符串是否为回文时,并不需要判断所有子字符串,可以进一步利用动态规划。

首先,若s[i...j]为回文,即A[i][j]为true,那么对于s[i-1...j+1]只需判断首位两个字符是否相等;同理,若s[i...j]不是回文,那么以该子字符串为中心的所有子字符串都不可能是回文。因此,用矩阵进行计算时,以每个字符为中心,向外扩展。这样较长的子字符串即可以利用较短的子字符串的计算结果,进一步避免了重复计算。需要注意的是,上面只讨论了以每一个字符为中心向外扩展,即子字符串为奇数的情况;同样需要讨论子字符串为偶数的情况。判断这种情况,仅需要以两个相邻的字符对进行扩展即可。

class Solution {
public:
    vector<string> trace;
    
    void dfs(const vector<vector<bool>>& record, const string& s, 
            int pos, vector<vector<string>>& result) {
        if (pos == (int)s.size()) {
            result.push_back(trace);
            return;
        }
        for (int i = pos; i < (int)s.size(); ++i) {
            if (record[pos][i]) {
                trace.push_back(s.substr(pos, i - pos + 1));
                dfs(record, s, i + 1, result);
                trace.pop_back();
            }
        }
    }
    
    vector<vector<string>> partition(string s) {
        vector<vector<bool>> record(s.size(), vector<bool>(s.size(), false));
        for (int i = 0; i < (int)s.size(); ++i) {
            record[i][i] = true;
            // odd length
            for (int j = 1; i - j >= 0 && i + j < (int)s.size(); ++j) {
                if (s[i-j] == s[i+j]) record[i-j][i+j] = true;
                else break;
            }
            // even length
            for (int j = 0; i - j >= 0 && i + 1 + j < (int)s.size(); ++j) {
                if (s[i-j] == s[i+1+j]) record[i-j][i+1+j] = true;
                else break;
            }
        }
        vector<vector<string>> result;
        dfs(record, s, 0, result);
        return result;
    }
};


总结:同样的,trace可以定义为static。算法的复杂度由DFS决定。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: