LeetCode-Palindrome Partitioning
还是回文数,不过这题是要找出所有可能的划分方法,没有太大的难度,主要是要对细节思考细心一点。
我的解法:
依然是DP的思想,保存每一个位置的所有划分方法,每一个合法的划分是一个字符串数组vector<string> subvec, 每个位置的划分方法则是所有不同合法划分组成的数组vector<vector<string>> res,则保存所有位置的可划分的解的是各个位置的划分方法组成的数组vector<vector<vector<string>>> parvec;
DP的公式推导:首先在已知s[0..j]的所有划分情况时,j + 1的划分方法等于所有可以j + 1构成回文的位置k(k >= 0 and k <= j + 1)之前的所有划分方法和[k, j + 1]这个回文组合构成的划分,即把s[k – 1]中每一个合法的划分加上[k, j + 1]回文构成的一个新的划分作为s[j + 1]的一个合法划分,不过要注意k == 0时的情况,此时k之前的合法划分为空。
1 class Solution { 2 public: 3 vector<vector<string>> partition(string s) { 4 // Start typing your C/C++ solution below 5 // DO NOT write int main() function 6 int n = s.size(); 7 vector<vector<string>> res; 8 vector<string> subvec; 9 if (n == 1) { 10 subvec.push_back(s); 11 res.push_back(subvec); 12 return res; 13 } 14 vector<vector<vector<string>>> parvec(n); 15 subvec.push_back(s.substr(0, 1)); 16 res.push_back(subvec); 17 parvec[0] = res; 18 for (int i = 1; i < n; i++) { 19 for (int j = 0; j <= i; j++) { 20 if (isPalindrome(s, j, i)) { 21 string rh = s.substr(j, i - j + 1); 22 if (j == 0) { 23 vector<string> pal; 24 pal.push_back(rh); 25 parvec[i].push_back(pal); 26 } 27 else { 28 for (vector<vector<string>>::iterator it = parvec[j - 1].begin(); 29 it != parvec[j - 1].end(); it++) { 30 vector<string> tmp = *it; 31 tmp.push_back(rh); 32 parvec[i].push_back(tmp); 33 } 34 } 35 36 } 37 } 38 } 39 return parvec[n - 1]; 40 } 41 bool isPalindrome(string &s, int start, int end) { 42 if (start == end) 43 return true; 44 for (int i = 0; i <= (end - start) / 2; i++) { 45 if (s[start + i] != s[end - i]) { 46 return false; 47 } 48 } 49 return true; 50 } 51 };