Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
Given s = "aab"
, return:
[
["aa","b"],
["a","a","b"]
]
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 dp
contains 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.
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 }