leetcode -- Palindrome Partitioning 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.

[解题思路]

记录所有合法的回文分割,最后得到最小的回文分割数,Large data TLE

 1 public class Solution {
 2     public int minCut(String s) {
 3         // Start typing your Java solution below
 4         // DO NOT write main() function
 5         ArrayList<ArrayList<String>> result = partition(s);
 6         int minCut = Integer.MAX_VALUE;
 7         for(int i = 0; i < result.size(); i++){
 8             if(result.get(i).size() < minCut){
 9                 minCut = result.get(i).size();
10             }
11         }
12         return minCut - 1;
13     }
14     
15     public ArrayList<ArrayList<String>> partition(String s) {
16         // Start typing your Java solution below
17         // DO NOT write main() function
18         ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();
19         ArrayList<String> output = new ArrayList<String>();
20         int depth = 0, len = s.length();
21         
22         palinPartition(s, 0, len, output, result);
23         return result;
24     }
25     
26     public void palinPartition(String s, int start, int len, ArrayList<String> output,
27                         ArrayList<ArrayList<String>> result){
28         if(start == len){
29             ArrayList<String> tmp = new ArrayList<String>();
30             tmp.addAll(output);
31             result.add(tmp);
32             return;
33         }
34         
35         for(int i = start; i < len; i++){
36             if(isPalindrome(s, start, i)){
37                 output.add(s.substring(start, i + 1));
38                 palinPartition(s, i + 1, len, output, result);
39                 output.remove(output.size() - 1);
40             }
41         }
42         
43     }
44     
45     public boolean isPalindrome(String s, int start, int end){
46         while(start < end){
47             if(s.charAt(start) != s.charAt(end)){
48                 return false;
49             }
50             start ++;
51             end --;
52         }
53         
54         return true;
55     }
56 }

 updated:

using DP

Let F(i) = min cut for s[i]…s[n-1] so F(0) is our answer and we have:

F(i) = min(1 + F(j))  for j = i + 1, …  n-1 and s[i]…s[j-1] is palidromic
F(i) = 0    if s[i]…s[n-1] is palindromic

 1 public static int minCut(String s) {
 2         // Start typing your Java solution below
 3         // DO NOT write main() function
 4         if (s == null) {
 5             return 0;
 6         }
 7         int len = s.length();
 8         int[] cuts = new int[len];
 9         for (int i = len - 1; i >= 0; i--) {
10             String str = s.substring(i);
11             if (isPalindrome(str)) {
12                 cuts[i] = 0;
13             } else {
14                 cuts[i] = getMin(s, i, len, cuts);
15             }
16         }
17         return cuts[0];
18     }
19 
20     public static int getMin(String s, int i, int len, int[] cuts) {
21         int min = Integer.MAX_VALUE;
22         for (int j = i + 1; j < len; j++) {
23             if (cuts[j] < min && isPalindrome(s.substring(i, j))) {
24                 min = cuts[j];
25             }
26         }
27         return min + 1;
28     }
29 
30     public static boolean isPalindrome(String s) {
31         int len = s.length();
32         int i = 0, j = len - 1;
33         while (i < j) {
34             if (s.charAt(i) != s.charAt(j)) {
35                 return false;
36             }
37             i++;
38             j--;
39         }
40         return true;
41     }
"a"    0    0    
   
"ab"    1    1    
   
"bb"    0    0    
   
"cdd"    1    1    
   
"dde"    1    1    
   
"efe"    0    0    
   
"fff"    0    0    
   
"abbab"    1    1    
   
"leet"    2    2    
   
"coder"    4    4    
   
"abcccb"    1    1    
   
"cabababcbc"    3    3    
   
"cbbbcc"    1    1    
   
"ccaacabacb"    3    3    
   
"racecar"    0    0    
   
"danaranad"    0    0    
   
"ababbbabbaba"    3    3    
   
"amanaplanacanalpanama"    0    0    
   
"seeslaveidemonstrateyetartsnomedievalsees"    0    0    
   
"eegiicgaeadbcfacfhifdbiehbgejcaeggcgbahfcajfhjjdgj"    42    42    
   
"kwtbjmsjvbrwriqwxadwnufplszhqccayvdhhvscxjaqsrmrrqngmuvxnugdzjfxeihogzsdjtvdmkudckjoggltcuybddbjoizu"    89    89    
   
"ltsqjodzeriqdtyewsrpfscozbyrpidadvsmlylqrviuqiynbscgmhulkvdzdicgdwvquigoepiwxjlydogpxdahyfhdnljshgjeprsvgctgnfgqtnfsqizonirdtcvblehcwbzedsmrxtjsipkyxk"    143    143    
   
"ababababababababababababcbabababababababababababa"    0    0    
   
"fifgbeajcacehiicccfecbfhhgfiiecdcjjffbghdidbhbdbfbfjccgbbdcjheccfbhafehieabbdfeigbiaggchaeghaijfbjhi"    75    75    
   
"apjesgpsxoeiokmqmfgvjslcjukbqxpsobyhjpbgdfruqdkeiszrlmtwgfxyfostpqczidfljwfbbrflkgdvtytbgqalguewnhvvmcgxboycffopmtmhtfizxkmeftcucxpobxmelmjtuzigsxnncxpaibgpuijwhankxbplpyejxmrrjgeoevqozwdtgospohznkoyzocjlracchjqnggbfeebmuvbicbvmpuleywrpzwsihivnrwtxcukwplgtobhgxukwrdlszfaiqxwjvrgxnsveedxseeyeykarqnjrtlaliyudpacctzizcftjlunlgnfwcqqxcqikocqffsjyurzwysfjmswvhbrmshjuzsgpwyubtfbnwajuvrfhlccvfwhxfqthkcwhatktymgxostjlztwdxritygbrbibdgkezvzajizxasjnrcjwzdfvdnwwqeyumkamhzoqhnqjfzwzbixclcxqrtniznemxeahfozp"    452    452    
   
"adabdcaebdcebdcacaaaadbbcadabcbeabaadcbcaaddebdbddcbdacdbbaedbdaaecabdceddccbdeeddccdaabbabbdedaaabcdadbdabeacbeadbaddcbaacdbabcccbaceedbcccedbeecbccaecadccbdbdccbcbaacccbddcccbaedbacdbcaccdcaadcbaebebcceabbdcdeaabdbabadeaaaaedbdbcebcbddebccacacddebecabccbbdcbecbaeedcdacdcbdbebbacddddaabaedabbaaabaddcdaadcccdeebcabacdadbaacdccbeceddeebbbdbaaaaabaeecccaebdeabddacbedededebdebabdbcbdcbadbeeceecdcdbbdcbdbeeebcdcabdeeacabdeaedebbcaacdadaecbccbededceceabdcabdeabbcdecdedadcaebaababeedcaacdbdacbccdbcece"    273    273    
   
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"    1    1
large data

已范错误:

line 23:

if (cuts[j] < min && isPalindrome(s.substring(i, j - 1)))
这里应是s.substring(i, j),表示i到j-1之间的字符串。
getMin函数的含义是:在i+1~n-2之间砍一刀,看之间的字符串是否是回文,如是则看看是否是最小值,如是则更新

可以改进的地方:
判断是否是回文也可以用dp来解

updated:2013/10/06

上面的解法的时间复杂度为O(n^3),值得优化的地方在判断字符串是否是回文,这个地方会有重复计算

1.计算字符串的所有子串是否是回文,DP解

  i.长度为1的子串都是回文

  ii.长度为2的子串:s[i]==s[j]

  iii.长度为其他的子串:s[i]==s[j] && matrix[i+1][j-1]

2.计算minCut,DP和上面相同

 1 public static int minCut(String s) {
 2         if (s == null || s.length() <= 1) {
 3             return 0;
 4         }
 5 
 6         int len = s.length();
 7         int[] dp = new int[len];
 8         boolean[][] palindromeMatrix = new boolean[len][len];
 9         for (int i = 0; i < len; i++) {
10             palindromeMatrix[i][i] = true;
11         }
12 
13         // DP to check every substring of s is palindrome or not?
14         // substring length start from 2 to n
15         for (int L = 2; L <= len; L++) {
16             for (int i = 0; i < len - L + 1; i++) {
17                 int j = i + L - 1;
18                 if (L == 2) {
19                     palindromeMatrix[i][j] = (s.charAt(i) == s.charAt(j));
20                 } else {
21                     palindromeMatrix[i][j] = (s.charAt(i) == s.charAt(j) && palindromeMatrix[i + 1][j - 1]);
22                 }
23             }
24         }
25 
26         for (int i = len - 1; i >= 0; i--) {
27             if(palindromeMatrix[i][len - 1]){
28                 dp[i] = 0;
29             } else {
30                 int min = Integer.MAX_VALUE;
31                 for (int k = i + 1; k < len; k++) {
32                     if(palindromeMatrix[i][k - 1])
33                         min = Math.min(min, 1 + dp[k]);
34                 }
35                 dp[i] = min;
36             }
37         }
38         return dp[0];
39     }

陈立人的博客里面说到:不太明白如何构建树来解决这个问题http://www.ituring.com.cn/article/57155

回文字串判断完毕之后,改如何计算最少分割呢?我们可以根据P构建一棵树,然后宽度有限遍历,找到树的最小深度。上面判断回文的时间复杂度为 O(n^2),构建树的时间复杂度为遍历一次P,时间复杂度也是O(n^2),最后树的遍历,时间复杂度要小于O(n^2),这样,整体的时间复杂度为 O(n^2)。





原文地址:https://www.cnblogs.com/feiling/p/3245919.html