131. 分割回文串

发布时间 2023-04-14 15:40:00作者: xiazichengxi

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

版本一

class Solution {
private:
    vector<vector<string>> result;
    vector<string> path; // 放已经回文的子串
    vector<vector<bool>> isPalindrome; // 放事先计算好的是否回文子串的结果
    void backtracking (const string& s, int startIndex) {
        // 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
        if (startIndex >= s.size()) {
            result.push_back(path);
            return;
        }
        for (int i = startIndex; i < s.size(); i++) {
            if (isPalindrome[startIndex][i]) {   // 是回文子串
                // 获取[startIndex,i]在s中的子串
                string str = s.substr(startIndex, i - startIndex + 1);
                path.push_back(str);
            } else {                                // 不是回文,跳过
                continue;
            }
            backtracking(s, i + 1); // 寻找i+1为起始位置的子串
            path.pop_back(); // 回溯过程,弹出本次已经填在的子串
        }
    }
    void computePalindrome(const string& s) {
        // isPalindrome[i][j] 代表 s[i:j](双边包括)是否是回文字串 
        isPalindrome.resize(s.size(), vector<bool>(s.size(), false)); // 根据字符串s, 刷新布尔矩阵的大小
        for (int i = s.size() - 1; i >= 0; i--) { 
            // 需要倒序计算, 保证在i行时, i+1行已经计算好了
            for (int j = i; j < s.size(); j++) {
                if (j == i) {isPalindrome[i][j] = true;}
                else if (j - i == 1) {isPalindrome[i][j] = (s[i] == s[j]);}
                else {isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i+1][j-1]);}
            }
        }
    }
public:
    vector<vector<string>> partition(string s) {
        result.clear();
        path.clear();
        computePalindrome(s);
        backtracking(s, 0);
        return result;
    }
};

版本2

class Solution {
private:
    bool judge_string(string s) {
        int lhs = 0;
        int rhs = s.size() - 1;
        while (lhs < rhs) {
            if (s[lhs] != s[rhs]) return false;
            lhs++;
            rhs--;
        }
        return true;
    }
    void traversal(string s, int lhs, int len) {
        string tmp(s, lhs, len);
        if (lhs == s.size()) {
            res.emplace_back(vec);
            return;
        }
        if (lhs + len > s.size()) return;
        if (lhs + len == s.size() && judge_string(tmp)) {
            vec.emplace_back(tmp);
            res.emplace_back(vec);
            vec.pop_back();
            return;
        }
        for (int i = len; lhs + i <= s.size(); i++) {
            tmp = string(s, lhs, i);
            int size = vec.size();
            if (judge_string(tmp)) {
                vec.emplace_back(tmp);
                traversal(s, lhs + i, 1);
                vec.pop_back();
            }
        }
    }
public:
    vector<vector<string>> res;
    vector<string> vec;
    vector<vector<string>> partition(string s) {
        res.clear();
        vec.clear();
        traversal(s, 0, 1);
        return res;
    }
};