问题
给定一个字符串s,切割s使该切割结果中每一个子串都是一个回文。
返回所有可能的回文分割集合。
例如,如果有s = "aab",
返回
[a,a,b]
[aa,b]
初始思路
有了回文分割II(Palindrome Partitioning II)的经验,这里很容易就可以得到递归分解子集的方案。只是在回文分割II中我们是统计切割次数,而这里要保存分割出来的子串。这里需要再强调一次枚举一个集合所有分割可能的经典递归循环,基本所有分割类问题都会用到:
if(start < s.size()) { size_t pos = start; while(pos < s.size()) { //入栈 MakePartition(result, oneResult, s, pos + 1); //出栈 ++pos; } } else { //得到一个解 }
具体到本问题,我们可以用一个vector保存一个解。于是上面的入栈操作就对应于push_back当前子串,出栈操作对应于pop_back,而得到一个解就对应于把该vector push_back到一个保存所有分割的二维vector中。
那么最终代码就出来了:
class Solution { public: vector<vector<string>> partition(string s) { std::vector<std::vector<std::string>> result; std::vector<std::string> oneResult; MakePartition(result, oneResult, s, 0); return result; } private: void MakePartition(std::vector<std::vector<std::string>>& result, std::vector<std::string>& oneResult, const std::string& s, size_t start) { if(start < s.size()) { size_t pos = start; while(pos < s.size()) { if(IsPalindrome(s, start, pos)) { oneResult.push_back(s.substr(start, pos - start + 1)); MakePartition(result, oneResult, s, pos + 1); oneResult.pop_back(); } ++pos; } } else { result.push_back(oneResult); } } bool IsPalindrome(const std::string& s, size_t start, size_t end) { bool result = true; while(start < end) { if(s[start] != s[end]) { result = false; break; } ++start; --end; } return result; } };
提交后Judge Large 52毫秒通过,看来这种枚举所有可能的问题优化空间不算太多。