题目
131. 分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: "aab"输出:[["aa","b"],["a","a","b"]]
题解
朴素解法
这道题很明显用递归来做,首先从左边取一个回文子串,然后将剩下的右子串再次调用函数递归,得到右子串的分割方案,然后将左回文子串添加到所有分割方案中,即得到了当前串的一部分分割方案。
只需将左边的回文串全遍历一遍,然后将分割方案汇总,便是所有的分割方案。
class Solution(object):def IsOK(self,s):for i in range(len(s)//2):if s[i]!=s[-i-1]:return Falsereturn Truedef partition(self, s):L=[]for i in range(len(s)):if self.IsOK(s[:i+1]):if len(s[i+1:])==0:L.append([s[:i+1]])breakres_list=self.partition(s[i+1:])for sub_list in res_list:L.append([s[:i+1]]+sub_list)return L
但是这种方法用时312 ms,只超过了9%的方案,因此可以继续优化。
优化
普通的递归最大的缺点就是重复情况太多,因此我们用一个字典储存已经得到的方案,这样下一次就不需要再计算一次:
class Solution(object):def __init__(self):self.D=dict()def IsOK(self,s):for i in range(len(s)//2):if s[i]!=s[-i-1]:return Falsereturn Truedef partition(self, s):if s in self.D:return self.D[s]L=[]for i in range(len(s)):if self.IsOK(s[:i+1]):if len(s[i+1:])==0:L.append([s[:i+1]])breakres_list=self.partition(s[i+1:])for sub_list in res_list:L.append([s[:i+1]]+sub_list)self.D[s]=Lreturn L
这次执行用时132 ms, 在所有 Python 提交中击败了86.82%的用户,可以说效果很好了。
看了其他题解之后,发现判断是否为回文串时,也会出现重复情况,因此对于该函数,我们也进行状态记录:
class Solution(object):def __init__(self):self.D=dict()self.S=dict()def IsOK(self,s):if len(s)<=1:return Trueelif s[0]!=s[-1]:return Falseelif s in self.D:return self.D[s]else:self.D[s]=self.IsOK(s[1:-1])return self.D[s]def partition(self, s):if s in self.D:return self.D[s]L=[]for i in range(len(s)):if self.IsOK(s[:i+1]):if len(s[i+1:])==0:L.append([s[:i+1]])breakres_list=self.partition(s[i+1:])for sub_list in res_list:L.append([s[:i+1]]+sub_list)self.D[s]=Lreturn L
执行用时:124 ms, 在所有 Python 提交中击败了88.47%的用户。
优化不是很明显,聊胜于无吧。
