题目:
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]
分析:
这道题其实是接着上一道题(验证回文串),要解答这道题,就应该先知道如何验证一个字符串是否是回文串。
不一样的地方在于对回文字符串的定义。
在上一道题里,回文串的定义是忽略了除字符数字意外的所有字符。
但是这道题里,从最终的结果看,可以只认为字符串里没有其他字符,因此逻辑上可以少写点。
首先就是先做一个函数来判断一个字符串是否是回文串:
思路就是做一次遍历,从头部和尾部分别拿单独的字符,进行一一对比,发现不一样就返回false
也可以如下:
def isPalindrome(self,s):
return s == s[::-1]
然后就是如何切割字符串了。
这道题还是需要用递归。
首先假设我们已经写好了函数
partition
,它可以返回一个字符串切割后的所有回文串的数组。我们先将字符串s切割出来第一个字符,命名为preStr。
如果preStr是回文串,我们就把后面的字符串suffixStr传入到partition
函数去获取到suffixStr字符串所有的回文串数组。拿到数组后,对数组进行循环遍历,每一个subList加上之前的preStr。就是将s切割第一个字符情况下所有回文串数组。将字符串s切割前两个字符串,命名为preStr,…… 依次这样做,直至最后。
代码如下:
def partition(self, s: str) -> List[List[str]]:
totalLen,result = len(s),[]
if totalLen <= 0:
return [[]]
if totalLen == 1:
return [[s]]
for index in range(1,totalLen+1):
preStr = s[0:index] #获取前面的字符串preStr
if self.isPalindrome(preStr): # 如果是回文串
nextAllList = self.partition(s[index:]) #获取后面的字符串suffixStr的所有回文串(递归调用函数)
preList = [preStr] # 将前面的字符串先包装成数组,以便于后面操作
if index == totalLen: # 如果是切割到最后,就直接添加preList,并跳出循环
result.append(preList)
break
for subList in nextAllList: # 遍历回文串数组,让每个子数组拼接上preList的元素
if subList :
result.append(preList+subList)
return result