Problem
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. Depth-first Search
public ArrayList<ArrayList<String>> partition(String s) { ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>(); if (s == null || s.length() == 0) { return result; } ArrayList<String> partition = new ArrayList<String>();//track each possible partition addPalindrome(s, 0, partition, result); return result; } private void addPalindrome(String s, int start, ArrayList<String> partition, ArrayList<ArrayList<String>> result) { //stop condition if (start == s.length()) { ArrayList<String> temp = new ArrayList<String>(partition); result.add(temp); return; } for (int i = start + 1; i <= s.length(); i++) { String str = s.substring(start, i); if (isPalindrome(str)) { partition.add(str); addPalindrome(s, i, partition, result); partition.remove(partition.size() - 1); } } } private boolean isPalindrome(String str) { int left = 0; int right = str.length() - 1; while (left < right) { if (str.charAt(left) != str.charAt(right)) { return false; } left++; right--; } return true; } |
2. Dynamic Programming
The dynamic programming approach is very similar to the problem of longest palindrome substring.
public static List<String> palindromePartitioning(String s) { List<String> result = new ArrayList<String>(); if (s == null) return result; if (s.length() <= 1) { result.add(s); return result; } int length = s.length(); int[][] table = new int[length][length]; // l is length, i is index of left boundary, j is index of right boundary for (int l = 1; l <= length; l++) { for (int i = 0; i <= length - l; i++) { int j = i + l - 1; if (s.charAt(i) == s.charAt(j)) { if (l == 1 || l == 2) { table[i][j] = 1; } else { table[i][j] = table[i + 1][j - 1]; } if (table[i][j] == 1) { result.add(s.substring(i, j + 1)); } } else { table[i][j] = 0; } } } return result; } |
Just some shorter version for recursive solution:
public static void palindrome(String input, List temp, List<List> result) {
for (int i = 1; i <= input.length(); i++) {
String str = input.substring(0, i);
if (isPalindrome(str)) {
List l = new ArrayList(temp);
l.add(str);
if (!input.substring(i, input.length()).isEmpty()) {
palindrome(input.substring(i, input.length()), l, result);
} else {
result.add(l);
}
}
}
}
public static void main(String[] args) {
String input = “aab”;
List<List> result = new ArrayList();
palindrome(input, new ArrayList(), result);
System.out.println(result);
}
is time complexity O(n^n) ?
Can you please explain how?
The Dynamic programming solution really just gives all possible palindromes. It doesn’t really partition the string in various ways,right?
You can find my discussion and Java implementation http://www.capacode.com/dynamic-programming/split-string-into-palindromes/.
using dfs is O(3^n)
Using dynamic method of complexity O(n*n)
public static List palindromePartitioning(String s) {
List result = new ArrayList();
if (s == null)
return result;
if(s.length() <=1) {
result.add(s);
return result;
}
int length = s.length();
int[][] table = new int[length][length];
//condition for calculate whole table
for (int l = 1; l <= length; l++) {
for (int i = 0; i <= length-l; i++) {
int j = i + l – 1;
if (s.charAt(i) == s.charAt(j)) {
if(l == 1 || l == 2) {
table[i][j] = 1;
} else {
table[i][j] = table[i + 1][j – 1];
}
if (table[i][j] == 1) {
result.add(s.substring(i, j + 1));
}
} else {
table[i][j] = 0;
}
}
}
return result;
}
what is complexity of above program?
Java is always pass-by-value.
http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
Nope, you cannot. Remember Java does pass by reference. So if you dont assign that temp to a new instance, all other temps will be changed.
Why do you assign partition to temp in the stop condition? Can you add partition to the result directly?