目錄
分割回文串
給定一個字符串 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;
}
};