leetcode 131 Palindrome Pairs

lc131 Palindrome Pairs

 

解法1:

递归

观察题目,要求,将原字符串拆成若干子串,且这些子串本身都为Palindrome

那么挑选cut的位置就很有意思,后一次cut可以建立在前一次cut的基础上

举例来说

"aab"

第一次cut"a" "ab"

第二次cut"a" "b"

 

很容易总结出规律,s(i, j)被i=<k<j,截断

若s(i,k)本身就是palindrome,那么我们只需要将s(i,k) 与s(k+1, j)的所有满足题目要求的子串组合,分别组合即可。

怎么求这些子串组合呢?递归解即可

 

 1 class Solution {
 2     public List<List<String>> partition(String s) {
 3         List<List<String>> res = new ArrayList<>();
 4         
 5         if(s.length() == 0)
 6             return res;
 7         if(s.length() == 1){
 8             res.add(Arrays.asList(s));
 9             return res;
10         }
11         
12         for(int i=0; i<s.length(); i++){
13             int x=0, y=i;
14             boolean preIsP = true;
15             while(x < y){
16                 if(s.charAt(x++) != s.charAt(y--)){
17                     preIsP = false;
18                     break;
19                 }
20             }
21             
22             if(preIsP){
23                 List<List<String>>laterRes = partition(s.substring(i+1));
24                 String pre = s.substring(0, i+1);
25                 for(int j=0; j < laterRes.size(); j++){
26                     
27                     List<String> tmp = new ArrayList<>(laterRes.get(j));
28                     tmp.add(0, pre);
29                     res.add(tmp);
30                 }
31                 if(i == s.length()-1){
32                     List<String> tmp = new ArrayList<>();
33                     tmp.add(0, pre);
34                     res.add(tmp);
35                 }
36             }
37         }
38         return res;
39     }
40 }

 

解法2:

dp解

这里要用到两个dp

一个一维pre[],表达s(0~i-1)所有满足题目的要求的结果

一个二维dp[][],表达s(i~j)是否为一个palindrome

 

更新方程:

若i和j相等,则需要看子串i+1~j-1是否为palindrome

当j-i<=1时,不存在子串,所以要考虑这种情况,加上一个||

if(s.charAt(i) == s.charAt(j)) && (dp[i+1][j-1] || j-i <=1)

  dp[i][j] == true

 

若s(i~j)已经是palindrome了,那么只需要把s(i~j)和所有满足条件的s(0~i-1)结果组合即可得到答案

所以要遍历pre[i]

把所有   {pre[i]中存放的结果  + s(i~j) }加入pre[i+1]

 

最后返回pre(s.length());

 1 class Solution {
 2     public List<List<String>> partition(String s) {
 3         List<List<String>>[] pre = new List[s.length()+1];
 4         pre[0] = new ArrayList<List<String>>();
 5         pre[0].add(new ArrayList<String>());
 6         
 7         boolean[][] isP = new boolean[s.length()][s.length()];
 8         
 9         for(int i=0; i<s.length(); i++){
10             pre[i+1] = new ArrayList<List<String>>();
11             for(int j=0; j<=i; j++){
12                 if(s.charAt(i) == s.charAt(j) && (i-j <= 1 || isP[j+1][i-1])){
13                     isP[j][i] = true;
14                     String str = s.substring(j, i+1);
15                     for(List<String> tmp : pre[j]){
16                         List<String> tmp2 = new ArrayList<>(tmp);
17                         tmp2.add(str);
18                         pre[i+1].add(tmp2);
19                     }
20                 }
21             }
22         }
23         return pre[s.length()];
24         
25         
26     }
27 }

 

posted @ 2019-06-21 14:16  南山南北秋悲  阅读(167)  评论(0编辑  收藏  举报