package string.recursive;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
public class PalindromePartitioning {
public List<List<String>> partition(String s) {
List<List<String>> partitions = new ArrayList<>();
boolean[][] memo = isPalindrome(s);
backtrack(s, 0, memo, new ArrayDeque<>(), partitions);
return partitions;
}
private void backtrack(String s, int start, boolean[][] memo, Deque<String> deque, List<List<String>> partitions) {
if (start >= s.length()) {
var partition = new ArrayList<>(deque);
partitions.add(partition);
return;
}
for (int end = start; end < s.length(); end++) {
if (!memo[start][end]) continue;
var substring = s.substring(start, end + 1);
deque.addLast(substring);
backtrack(s, end + 1, memo, deque, partitions);
deque.removeLast();
}
}
private boolean[][] isPalindrome(String s) {
int n = s.length();
boolean[][] memo = new boolean[n][n];
for (int end = 0; end < n; end++)
for (int start = 0; start <= end; start++)
if (s.charAt(start) == s.charAt(end) && (end - start < 2 || memo[start + 1][end - 1]))
memo[start][end] = true;
return memo;
}
}