Sponsored
Sponsored
Recursive Backtracking: This approach involves using recursion to explore all possible ways to partition the string. At each position, we check all possible substrings starting from that position, and if a substring is palindrome, we recursively partition the remaining substring. This way, we build possible partitions incrementally.
Time Complexity: O(2n * n), since we can have 2^n possible partitions and checking each partition takes O(n).
Space Complexity: O(n), where n is the depth of the recursive call stack.
1import java.util.*;
2
3public class Solution {
4 private boolean isPalindrome(String s, int low, int high) {
5 while (low < high) {
6 if (s.charAt(low++) != s.charAt(high--)) {
7 return false;
8 }
9 }
10 return true;
11 }
12
13 private void backtrack(int start, List<String> path, List<List<String>> res, String s) {
14 if (start == s.length()) {
15 res.add(new ArrayList<>(path));
16 return;
17 }
18 for (int end = start + 1; end <= s.length(); end++) {
19 if (isPalindrome(s, start, end - 1)) {
20 path.add(s.substring(start, end));
21 backtrack(end, path, res, s);
22 path.remove(path.size() - 1);
23 }
24 }
25 }
26
27 public List<List<String>> partition(String s) {
28 List<List<String>> res = new ArrayList<>();
29 backtrack(0, new ArrayList<>(), res, s);
30 return res;
31 }
32
33 // Example Usage
34 // public static void main(String[] args) {
35 // Solution sol = new Solution();
36 // System.out.println(sol.partition("aab"));
37 // }
38}
This Java code uses a backtracking approach similar to the Python solution. The backtrack
method partitions the string from a start
index by checking each possible substring for palindromicity using the isPalindrome
method. If a palindrome is found, it is added to the path
, and the method is called recursively. Eventually, when the end of the string is reached, the current path
is added to res
.
Dynamic Programming with Backtracking: This approach utilizes dynamic programming to precompute whether substrings are palindromes, reducing the on-the-fly palindrome check complexity in backtracking.
Time Complexity: O(n2 + 2n * n). Filling the dp
table takes O(n2), and backtracking takes O(2n * n).
Space Complexity: O(n2), required for the dp
table.
1#include <vector>
2#include <string>
3using namespace std;
4
5class Solution {
public:
vector<vector<string>> partition(string s) {
int n = s.length();
vector<vector<bool>> dp(n, vector<bool>(n, false));
vector<vector<string>> res;
// Fill the DP table
for (int i = 0; i < n; ++i) dp[i][i] = true; // Single character palindrome
for (int length = 2; length <= n; ++length) {
for (int start = 0; start <= n - length; ++start) {
int end = start + length - 1;
if (length == 2)
dp[start][end] = (s[start] == s[end]);
else
dp[start][end] = (s[start] == s[end]) && dp[start + 1][end - 1];
}
}
vector<string> path;
backtrack(0, path, res, dp, s);
return res;
}
private:
void backtrack(int start, vector<string>& path, vector<vector<string>>& res, vector<vector<bool>>& dp, string& s) {
if (start == s.length()) {
res.push_back(path);
return;
}
for (int end = start; end < s.length(); ++end) {
if (dp[start][end]) {
path.push_back(s.substr(start, end - start + 1));
backtrack(end + 1, path, res, dp, s);
path.pop_back();
}
}
}
// Example Usage
// int main() {
// Solution sol;
// auto result = sol.partition("aab");
// for (const auto& partition : result) {
// for (const auto& part : partition) {
// cout << part << " ";
// }
// cout << endl;
// }
// }
};
This C++ solution creates a dynamic programming table dp
to determine if substrings are palindromes. It proceeds with a backtracking approach to explore all possible palindrome partitions. The precomputed dp
table allows quick palindrome checks during partitioning, enhancing efficiency.