Palindrome Partitioning I & II

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

Return all possible palindrome partitioning of s.

Example

Given s = "aab", return:

[
  ["aa","b"],
  ["a","a","b"]
]
分析:
创建一个method partition 用于把一个string str分成多个palindrome. 怎么做呢?既然是分割,那么那个分割点就是在每两个字符中间。所以,先把str分成两段,[0, i] and [i + 1, n],看第一段是否是palindrome,是的话,递归调用partition,并且把第二段传进去。然后把得到的list和第一段合并。
 1 public class Solution {
 2     public List<List<String>> partition(String str) {
 3         List<List<String>> listAll = new ArrayList<>();
 4         if (str== null || str.length() == 0) return listAll;
 5 
 6         for (int i = 1; i <= str.length(); i++) {
 7             String strPart1 = str.substring(0, i);
 8             String strPart2 = str.substring(i);
 9 
10             if (isPalindrome(strPart1)) {
11                 if (strPart1.equals(str)) {
12                     List<String> list = new ArrayList<>();
13                     list.add(str);
14                     listAll.add(list);
15                 } else {
16                     List<List<String>> temp = partition(strPart2);
17                     for (int j = 0; j < temp.size(); j++) {
18                         temp.get(j).add(0, strPart1);
19                         listAll.add(new ArrayList<String>(temp.get(j)));
20                     }
21                 }
22             }
23         }
24         return listAll;
25     }
26 
27     public boolean isPalindrome(String str) {
28         if (str == null || str.length() == 1) return true;
29 
30         int i = 0, j = str.length() - 1;
31         while (i < j) {
32             if (str.charAt(i) != str.charAt(j)) {
33                 return false;
34             }
35             i++;
36             j--;
37         }
38         return true;
39     }
40 }

另一种方法:https://leetcode.com/problems/palindrome-partitioning/discuss/41982/Java-DP-%2B-DFS-solution

first, I ask myself that how to check if a string is palindrome or not, usually a two point solution scanning from front and back. Here if you want to get all the possible palindrome partition, first a nested for loop to get every possible partitions for a string, then a scanning for all the partitions. That's a O(n^2) for partition and O(n^2) for the scanning of string, totaling at O(n^4) just for the partition. However, if we use a 2d array to keep track of any string we have scanned so far, with an addition pair, we can determine whether it's palindrome or not by justing looking at that pair, which is this line if(s.charAt(i) == s.charAt(j) && (i - j <= 2 || dp[j+1][i-1])). This way, the 2d array dpcontains the possible palindrome partition among all.

class Solution {
    public List<List<String>> partition(String s) {
        List<List<String>> res = new ArrayList<>();
        boolean[][] dp = new boolean[s.length()][s.length()];
        for (int i = 0; i < s.length(); i++) {
            for (int j = 0; j <= i; j++) {
                if (s.charAt(i) == s.charAt(j) && (i - j <= 2 || dp[j + 1][i - 1])) {
                    dp[j][i] = true;
                }
            }
        }
        helper(res, new ArrayList<>(), dp, s, 0);
        return res;
    }

    private void helper(List<List<String>> res, List<String> path, boolean[][] dp, String s, int pos) {
        if (pos == s.length()) {
            res.add(new ArrayList<>(path));
            return;
        }

        for (int i = pos; i < s.length(); i++) {
            if (dp[pos][i]) {
                path.add(s.substring(pos, i + 1));
                helper(res, path, dp, s, i + 1);
                path.remove(path.size() - 1);
            }
        }
    }
}

Palindrome Partitioning II

Given a string s, cut s into some substrings such that every substring is a palindrome.

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

Example

Given s = "aab",

Return 1 since the palindrome partitioning ["aa", "b"] could be produced using 1 cut.

分析:

用cuts[i]表示从0 到 i最小的cuts数。那么为了得到cuts[i], 我们需要从0到i,看string 的k (0 <= k < i) 到 i部分是否是palindrome。是的话,我们需要更新当前cuts[i]的值,因为我们有可能在这个时候找到一个更小的值。

 1 public class Solution {
 2 
 3     public int minCut(String s) {
 4         if (s == null || s.length() <= 1) return 0;
 5         
 6         int[] cuts = new int[s.length()];
 7         for (int i = 1; i < cuts.length; i++) {
 8             cuts[i] = i;
 9         }
10         
11         for (int i = 1; i < cuts.length; i++) {
12             if (isPalindrome(s, 0, i)) {
13                 cuts[i] = 0;
14                 continue;
15             }
16             
17             for (int j = 1; j <= i; j++) {
18                 if (isPalindrome(s, j, i)) {
19                     cuts[i] = Math.min(cuts[i], cuts[j - 1] + 1);
20                 }
21             }
22         }
23         return cuts[s.length() - 1];
24     }
25     
26     public boolean isPalindrome(String str, int start, int end) {
27         while(start < end) {
28             if (str.charAt(start) != str.charAt(end)) {
29                 return false;
30             }
31             start++;
32             end--;
33         }
34         return true;
35     }
36 }

 

posted @ 2016-07-09 09:23  北叶青藤  阅读(194)  评论(0编辑  收藏  举报