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: Input: s = "aab" Output: [["a","a","b"],["aa","b"]]
Input: s = "a" Output: [["a"]]
Constraints: 1 <= s.length <= 16 s contains only lowercase English letters.
class Solution:
def partition(self, s: str) -> list[list[str]]:
res = []
n = len(s)
def isPalindrome(sub):
return sub == sub[::-1]
def backtrack(start, path):
if start == n:
res.append(path[:]) # Append a copy of the current path
return
for i in range(start, n):
sub = s[start:i+1]
if isPalindrome(sub):
path.append(sub)
backtrack(i+1, path)
path.pop()
backtrack(0, [])
return res
partition(self, s: str) -> list[list[str]]
: This is the main function that takes a string s
as input and returns a list of lists of strings, where each inner list represents a palindrome partitioning of s
.
res = []
: Initializes an empty list res
to store the resulting palindrome partitions.
n = len(s)
: Gets the length of the input string s
and stores it in n
.
isPalindrome(sub)
: A helper function to check if a given substring sub
is a palindrome. It returns True
if sub
is a palindrome, and False
otherwise. It achieves this by comparing the substring with its reverse.
backtrack(start, path)
: A recursive function that performs backtracking to find all possible palindrome partitions.
start
: The starting index of the current substring being considered.path
: A list representing the current palindrome partition being built.Base Case:
if start == n:
: If start
reaches the end of the string (i.e., start == n
), it means a valid palindrome partition has been found. A copy of the path
is appended to res
. It's important to append a copy path[:]
instead of path
directly because path
is modified during the backtracking process. Appending path
directly would mean that all lists in res
would eventually point to the same (empty) list.Recursive Step:
for i in range(start, n):
: Iterates through the string from the current start
index to the end of the string.sub = s[start:i+1]
: Extracts a substring sub
from s
starting at start
and ending at i+1
.if isPalindrome(sub):
: Checks if the extracted substring sub
is a palindrome using the isPalindrome
helper function.
sub
is a palindrome:
path.append(sub)
: Appends the palindrome sub
to the current path
.backtrack(i+1, path)
: Recursively calls the backtrack
function with the updated start
index (i+1
) and the updated path
. This continues the partitioning process from the next character after the current palindrome.path.pop()
: After the recursive call returns, the last added palindrome sub
is removed from the path
. This is the backtracking step, which allows exploring other possible partitions.backtrack(0, [])
: Initiates the backtracking process by calling the backtrack
function with an initial start
index of 0 and an empty path
.
return res
: Returns the list res
containing all the palindrome partitions.
The brute force solution would involve generating all possible substrings and checking if each substring is a palindrome. Then, recursively explore the remaining string after each palindrome substring. This approach has a high time complexity because it explores all possible substrings, even those that are not palindromes.
The time complexity is difficult to precisely determine due to the nature of the backtracking algorithm. However, we can make some observations.
isPalindrome
can take O(n) time. The copying of path takes O(n) time. So each complete path takes O(n) to compute.isPalindrome
check takes O(n) time in the worst case.Therefore, a reasonable estimate of the worst-case time complexity is O(n * 2^n).
res
list and the path
list.path
list stores at most n strings.res
list can store an exponential number of partitions (O(2^n)). Each partition can have at most n strings.Therefore, the space complexity is O(n * 2^n) in the worst case, mainly due to the space required to store the results.
Empty String: If the input string s
is empty, the function should return a list containing an empty list. The code handles this case correctly because the loop for i in range(start, n)
will not execute when n
is 0.
Single Character String: If the input string s
has only one character, the function should return a list containing a list with that single character. The code handles this correctly because the isPalindrome
function will return true and `[[