leetcode 131. Palindrome Partitioning

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Example:

Input: "aab"
Output:
[
  ["aa","b"],
  ["a","a","b"]
]

题目大意:给定一个字符串s,对其进行划分,是的划分后的所有字串都是回文串, 返回所有可能的划分。

 

思路:回溯法

 1 class Solution {
 2 public:
 3     vector<vector<string>> partition(string s) {
 4         vector<vector<string> > res;
 5         vector<string> temp;
 6         backtrack(s, 0, temp, res);
 7         return res;
 8     }
 9 private:
10     bool isPalindrome(string s, int i, int j) {
11         while (i < j) {
12             if (s[i] != s[j])
13                 return false;
14             i++;
15             j--;
16         }
17         return true;
18     }
19     void backtrack(string &s, int i, vector<string> &v, vector<vector<string>> &res) {
20         if ((i == s.length()) && !v.empty()) {
21             res.push_back(v);
22             return ;
23         }
24         for (int k = i; k < s.length(); ++k) {
25             if (isPalindrome(s, i, k)) {
26                 v.push_back(s.substr(i, k - i + 1));
27                 backtrack(s, k + 1, v, res);
28                 v.pop_back();
29             }
30         }
31     }
32 };

时间复杂度:

T(n) = n * [T(n - 1) + ... + T(1)]

T(n + 1) = (n + 1) * [ T(n) + T(n - 1) + ... + T(1)] = (n + 1) * [ T(n) + 1/n * T(n)]

==> T(n) = n * 2^n

优化:判断回文串的时候有大量重复。

 1 class Solution {
 2 public:
 3     vector<vector<string>> partition(string s) {
 4         int n = s.size();
 5         vector<vector<int>> dp(n, vector<int>(n, 0)); //dp[i][j]表示下表i到下表j的字串是否为回文串
 6         for (int i = 0; i < n; i++) {
 7             dp[i][i] = 1;
 8         }
 9         
10         for (int i = 0; i < n - 1; i++) {
11             if (s[i] == s[i+1]) {
12                 dp[i][i+1] = 1;
13             }
14         }
15         
16         for (int len = 2; len < n; len++) {
17             for (int i = 0; i < n; i++) {
18                 if (i + len >= n) {
19                     break;
20                 } else {
21                     if (s[i] == s[i + len]) {
22                         dp[i][i+len] = dp[i+1][i+len-1] || dp[i][i+len];
23                     }
24                 }
25             }
26         }
27         vector<vector<string> > res;
28         vector<string> temp;
29         backtrack(s, 0, temp, res, dp);
30         return res;
31     }
32 private:
33     void backtrack(string &s, int i, vector<string> &v, vector<vector<string>> &res, vector<vector<int>> &dp) {
34         if ((i == s.length()) && !v.empty()) {
35             res.push_back(v);
36             return ;
37         }
38         for (int k = i; k < s.length(); ++k) {
39             if (dp[i][k]) {
40                 v.push_back(s.substr(i, k - i + 1));
41                 backtrack(s, k + 1, v, res, dp);
42                 v.pop_back();
43             }
44         }
45     }
46 };

 

posted @ 2019-11-22 21:48  琴影  阅读(302)  评论(0编辑  收藏  举报