2018年力扣高頻算法面試題5字符串

分割回文串

給定一個字符串 s,將 s 分割成一些子串,使每個子串都是迴文串。
返回 s 所有可能的分割方案。
示例:
輸入: “aab”
輸出:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]
分析:DFS—既然題目要求找到所有可能拆分成迴文數的情況,那麼肯定是所有的情況都要遍歷到,對於每一個子字符串都要分別判斷一次是不是迴文數,那麼肯定有一個判斷迴文數的子函數,還需要一個DFS函數用來遞歸,再加上原本的這個函數,總共需要三個函數來求解。
我們將已經檢測好的迴文子串放到字符串數組out中,當s遍歷完了之後,將out加入結果res中。那麼在遞歸函數中我們必須要知道當前遍歷到的位置,用變量start來表示,所以在遞歸函數中,如果start等於字符串s的長度,說明已經遍歷完成,將out加入結果res中,並返回。否則就從start處開始遍歷,由於不知道該如何切割,所以我們要遍歷所有的切割情況,即一個字符,兩個字符,三個字符,等等。。
首先判斷取出的子串是否是迴文串,調用一個判定迴文串的子函數即可,這個子函數傳入了子串的起始和終止的範圍,若子串是迴文串,那麼我們將其加入out,並且調用遞歸函數,此時start傳入 i+1,之後還要恢復out的狀態。

class Solution {
public:
    vector<vector<string>> partition(string s) {
        vector<vector<string>> res;
        vector<string> out;
        helper(s, 0, out, res);
        return res;
    }
    void helper(string s, int start, vector<string>& out, vector<vector<string>>& res) {
        if (start == s.size()) { res.push_back(out); return; }
        for (int i = start; i < s.size(); ++i) {
            if (!isPalindrome(s, start, i)) continue;
            out.push_back(s.substr(start, i - start + 1));
            helper(s, i + 1, out, res);
            out.pop_back();
        }
    }
    bool isPalindrome(string s, int start, int end) {
        while (start < end) {
            if (s[start] != s[end]) return false;
            ++start; --end;
        }
        return true;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章