palindrome-partitioning I&II——回文切割深度遍历

Posted 鸭子船长

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了palindrome-partitioning I&II——回文切割深度遍历相关的知识,希望对你有一定的参考价值。

I:

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

Return all possible palindrome partitioning of s.

For example, given s ="aab",
Return

  [
    ["aa","b"],
    ["a","a","b"]
  ]

先切割,而后判断是否为回文。若是,则将剩余部分继续进行深度遍历。
 1 class Solution {
 2 public:
 3     vector<vector<string>> partition(string s) {
 4         if(s.length()<1) return res;
 5         dfs(s,0);
 6         return res;
 7     }
 8     
 9     void dfs(string s,int n){
10         int len=s.length();
11         if(n==len){
12             res.push_back(v);
13             return ;
14         }
15         for(int i=1;i<len-n+1;i++){
16             string tmp=s.substr(n,i);
17             if(isPalindrome(tmp)){
18                 v.push_back(tmp);
19                 dfs(s,n+i);
20                 v.pop_back();
21             }
22         }
23     }
24     
25     bool isPalindrome(string s){
26         int n=s.length();
27         int i=0,j=n-1;
28         while(i<j){
29             if(s[i]!=s[j])
30                 return false;
31             i++;
32             j--;
33         }
34         return true;
35     }
36     vector<string> v;
37     vector<vector<string>> res;
38 };

II:

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

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

 

从后往前构造二维数组isPalin,用于存储已经确定的回文子串。isPalin[i][j]==true代表s[i,...,j]是回文串。

在构造isPalin的同时使用动态规划计算从后往前的最小切分数,记录在min数组中。min[i]代表s[i,...,n-1]的最小切分数。

(上述两步分开做会使得代价翻倍,容易TLE)

关键步骤:

1、min[i]初始化为min[i+1]+1,即初始化s[i]与s[i+1]之间需要切一刀。这里考虑边界问题,因此min数组设为n+1长度。

2、从i到n-1中间如果存在位置j,同时满足:(1)s[i,...,j]为回文串;(2)1+min[j+1] < min[i]。

那么min[i]=1+min[j+1],也就是说一刀切在j的后面比切在i的后面要好。

 

 1 class Solution {
 2 public:
 3     int minCut(string s) {
 4         int n=s.length();
 5         if(n==1) return 0;
 6         vector<vector<bool>> isPali(n,vector<bool>(n,false));
 7         vector<int> min(n+1,-1);
 8         for(int i=0;i<n;i++){
 9             isPali[i][i]=true;
10         }
11         for(int i=n-1;i>=0;i--){
12             min[i]=min[i+1]+1;
13             for(int j=i+1;j<n;j++){
14                 if(s[i]==s[j]){
15                     if(j==i+1||isPali[i+1][j-1]==true){
16                         isPali[i][j]=true;
17                         if(j==n-1)
18                             min[i]=0;
19                         else if(min[i]>min[j+1]+1)
20                             min[i]=min[j+1]+1;
21                     }
22                 }
23             }
24         }
25         return min[0];
26     }
27 };

 

以上是关于palindrome-partitioning I&II——回文切割深度遍历的主要内容,如果未能解决你的问题,请参考以下文章

LeetcodePalindrome Partitioning

算法——回文串专题

131. 分割回文串

回溯算法--分割回文串

131. 分割回文串

131 Palindrome Partitioning 分割回文串