Palindrome Partitioning
Palindrome Partitioning:
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.
Try this Problem on your own or check similar problems:
Solution:
- Java
- JavaScript
- Python
- C++
class Solution {
public List<List<String>> partition(String s) {
List<List<String>> result = new ArrayList<>();
helper(s, 0, new ArrayList<>(), result);
return result;
}
private void helper(String s, int start, List<String> currentList, List<List<String>> result){
if(s.length() == start){
result.add(new ArrayList<>(currentList));
return;
}
for(int i = start; i < s.length(); ++i){
String subString = s.substring(start, i+1);
if(isPalindrome(subString)){
currentList.add(subString);
helper(s, i + 1, currentList, result);
currentList.remove(currentList.size()-1);
}
}
}
private boolean isPalindrome(String s){
int start = 0, end = s.length()-1;
while(start < end){
if(s.charAt(start) != s.charAt(end)) return false;
++start;
--end;
}
return true;
}
}
/**
* @param {string} s
* @return {string[][]}
*/
var partition = function (s) {
const result = [];
helper(s, 0, [], result);
return result;
};
function helper(s, start, currentList, result) {
if (start === s.length) {
result.push([...currentList]);
return;
}
for (let i = start; i < s.length; ++i) {
const subString = s.substring(start, i + 1);
if (isPalindrome(subString)) {
currentList.push(subString);
helper(s, i + 1, currentList, result);
currentList.pop();
}
}
}
function isPalindrome(s) {
let start = 0;
let end = s.length - 1;
while (start < end) {
if (s[start] !== s[end]) return false;
start++;
end--;
}
return true;
}
class Solution:
def partition(self, s: str) -> List[List[str]]:
result = []
self.helper(s, 0, [], result)
return result
def helper(self, s: str, start: int, currentList: List[str], result: List[List[str]]) -> None:
if start == len(s):
result.append(currentList[:])
return
for i in range(start, len(s)):
subString = s[start:i + 1]
if self.isPalindrome(subString):
currentList.append(subString)
self.helper(s, i + 1, currentList, result)
currentList.pop()
def isPalindrome(self, s: str) -> bool:
start, end = 0, len(s) - 1
while start < end:
if s[start] != s[end]:
return False
start += 1
end -= 1
return True
class Solution {
public:
vector<vector<string>> partition(string s) {
vector<vector<string>> result;
helper(s, 0, {}, result);
return result;
}
private:
void helper(const string& s, int start, vector<string> currentList, vector<vector<string>>& result) {
if (s.length() == start) {
result.push_back(currentList);
return;
}
for (int i = start; i < s.length(); ++i) {
string subString = s.substr(start, i - start + 1);
if (isPalindrome(subString)) {
currentList.push_back(subString);
helper(s, i + 1, currentList, result);
currentList.pop_back();
}
}
}
bool isPalindrome(const string& s) {
int start = 0, end = s.length() - 1;
while (start < end) {
if (s[start] != s[end])
return false;
++start;
--end;
}
return true;
}
};
Time/Space Complexity:
- Time Complexity: O(n*2^n)
- Space Complexity: O(n)
Explanation:
Another backtracking problem, where we use the same approach/template we did for all backtracking problems (e.g. Combinations). The bulk logic is again in the helper function, where we check if current substring is palindrome (with the isPalindrome
function which just iterates over the string simultaneously from left and right and checks for equality which is the definition of palindrome - reads the same from left to right and right to left). If the current substring is a palindrome, we add it to the current partition list currentList
and call the helper function to search for all remaining partitions in the rest of the string. Recursion stack is n
(length of the string) deep so that's our space complexity, the time complexity is O(n\*2^n)
as always we have the n
multiplier (for checking whether the string is a palindrome and also coping the currentList to the result, worst case every character is palindrome by itself so we will have n lists), and for the recursion we have in total 2^n
nodes (the reasining behind this is that there are in total 2^n
different partitions of any string).
As always after the helper function call, we backtrack and remove our current candidate from our partition list.