Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s.
Example 1:
Input: s = "aab"
Output: [["a","a","b"],["aa","b"]]
Example 2:
Input: s = "a"
Output: [["a"]]
Constraints:
1 <= s.length <= 16
s contains only lowercase English letters.
Solutions
Solution 1: Preprocessing + DFS (Backtracking)
Thinking
List every way to cut \(s\) into palindromic pieces. \(n\le 16\), so at most \(2^{n-1}\) partitions; backtracking is fine. Checking palindromes at each cut rescans the same spans.
Precompute \(f[i][j]\) whether \(s[i..j]\) is a palindrome, then try the next cut only when \(f[i][j]\) is true.
We can use dynamic programming to preprocess whether any substring in the string is a palindrome, i.e., \(f[i][j]\) indicates whether the substring \(s[i..j]\) is a palindrome.
Next, we design a function \(dfs(i)\), which represents starting from the \(i\)-th character of the string and partitioning it into several palindromic substrings, with the current partition scheme being \(t\).
If \(i = |s|\), it means the partitioning is complete, and we add \(t\) to the answer array and then return.
Otherwise, we can start from \(i\) and enumerate the end position \(j\) from small to large. If \(s[i..j]\) is a palindrome, we add \(s[i..j]\) to \(t\), then continue to recursively call \(dfs(j+1)\). When backtracking, we need to pop \(s[i..j]\).
The time complexity is \(O(n \times 2^n)\), and the space complexity is \(O(n^2)\). Here, \(n\) is the length of the string.