题目

131. 分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:

  1. 输入: "aab"
  2. 输出:
  3. [
  4. ["aa","b"],
  5. ["a","a","b"]
  6. ]

题解

朴素解法

这道题很明显用递归来做,首先从左边取一个回文子串,然后将剩下的右子串再次调用函数递归,得到右子串的分割方案,然后将左回文子串添加到所有分割方案中,即得到了当前串的一部分分割方案。
只需将左边的回文串全遍历一遍,然后将分割方案汇总,便是所有的分割方案。

  1. class Solution(object):
  2. def IsOK(self,s):
  3. for i in range(len(s)//2):
  4. if s[i]!=s[-i-1]:
  5. return False
  6. return True
  7. def partition(self, s):
  8. L=[]
  9. for i in range(len(s)):
  10. if self.IsOK(s[:i+1]):
  11. if len(s[i+1:])==0:
  12. L.append([s[:i+1]])
  13. break
  14. res_list=self.partition(s[i+1:])
  15. for sub_list in res_list:
  16. L.append([s[:i+1]]+sub_list)
  17. return L

但是这种方法用时312 ms,只超过了9%的方案,因此可以继续优化。

优化

普通的递归最大的缺点就是重复情况太多,因此我们用一个字典储存已经得到的方案,这样下一次就不需要再计算一次:

  1. class Solution(object):
  2. def __init__(self):
  3. self.D=dict()
  4. def IsOK(self,s):
  5. for i in range(len(s)//2):
  6. if s[i]!=s[-i-1]:
  7. return False
  8. return True
  9. def partition(self, s):
  10. if s in self.D:
  11. return self.D[s]
  12. L=[]
  13. for i in range(len(s)):
  14. if self.IsOK(s[:i+1]):
  15. if len(s[i+1:])==0:
  16. L.append([s[:i+1]])
  17. break
  18. res_list=self.partition(s[i+1:])
  19. for sub_list in res_list:
  20. L.append([s[:i+1]]+sub_list)
  21. self.D[s]=L
  22. return L

这次执行用时132 ms, 在所有 Python 提交中击败了86.82%的用户,可以说效果很好了。

看了其他题解之后,发现判断是否为回文串时,也会出现重复情况,因此对于该函数,我们也进行状态记录:

  1. class Solution(object):
  2. def __init__(self):
  3. self.D=dict()
  4. self.S=dict()
  5. def IsOK(self,s):
  6. if len(s)<=1:
  7. return True
  8. elif s[0]!=s[-1]:
  9. return False
  10. elif s in self.D:
  11. return self.D[s]
  12. else:
  13. self.D[s]=self.IsOK(s[1:-1])
  14. return self.D[s]
  15. def partition(self, s):
  16. if s in self.D:
  17. return self.D[s]
  18. L=[]
  19. for i in range(len(s)):
  20. if self.IsOK(s[:i+1]):
  21. if len(s[i+1:])==0:
  22. L.append([s[:i+1]])
  23. break
  24. res_list=self.partition(s[i+1:])
  25. for sub_list in res_list:
  26. L.append([s[:i+1]]+sub_list)
  27. self.D[s]=L
  28. return L

执行用时:124 ms, 在所有 Python 提交中击败了88.47%的用户。
优化不是很明显,聊胜于无吧。