文章目录
一、题目
二、思路
具体例子和步骤:假设 s = "aab"
,步骤如下:
-
初始状态:
s = "aab"
path = []
res = []
-
第一层递归(外层循环):
path = []
- 检查
s[:1]
即a
(是回文):- 递归调用
dfs("ab", ["a"], res)
- 递归调用
-
第二层递归:
s = "ab"
path = ["a"]
- 检查
s[:1]
即a
(是回文):- 递归调用
dfs("b", ["a", "a"], res)
- 递归调用
-
第三层递归:
s = "b"
path = ["a", "a"]
- 检查
s[:1]
即b
(是回文):- 递归调用
dfs("", ["a", "a", "b"], res)
- 递归调用
-
终止条件:
s = ""
path = ["a", "a", "b"]
res
加入path
,即res = [["a", "a", "b"]]
-
回溯并尝试新的分割:
- 回溯至
s = "ab"
,path = ["a"]
- 检查
s[:2]
即ab
(不是回文),跳过。 - 回溯至初始状态,
s = "aab"
,path = []
- 检查
s[:2]
即aa
(是回文):- 递归调用
dfs("b", ["aa"], res)
- 递归调用
- 回溯至
-
新的递归路径:
s = "b"
path = ["aa"]
- 检查
s[:1]
即b
(是回文):- 递归调用
dfs("", ["aa", "b"], res)
- 递归调用
-
终止条件:
s = ""
path = ["aa", "b"]
res
加入path
,即res = [["a", "a", "b"], ["aa", "b"]]
plain
Initial call: dfs("aab", [])
|
|-- dfs("ab", ["a"])
| |
| |-- dfs("b", ["a", "a"])
| | |
| | |-- dfs("", ["a", "a", "b"]) --> Add to result [["a", "a", "b"]]
| |
| `-- dfs("b", ["a"]) -- "ab" 不是回文,跳过
|
`-- dfs("b", ["aa"])
|
|-- dfs("", ["aa", "b"]) --> Add to result [["a", "a", "b"], ["aa", "b"]]
代码逻辑:
for i in range(1, len(s) + 1)
:循环从1开始到len(s)
,尝试每一个可能的分割位置。if self.isP(s[:i])
:检查从0到i
的子串s[:i]
是否是回文。self.dfs(s[i:], path + [s[:i]], res)
:如果s[:i]
是回文,将s[:i]
添加到路径path
中,递归处理剩余的字符串s[i:]
。
每次递归调用会传递新的字符串 s
和更新后的路径 path
(这个路径即当前方案的所有字符组合列表),直到字符串 s
为空,此时将路径 path
添加到结果列表 res
中。这样,通过递归和回溯的方法,我们可以找到所有可能的分割方案。递归调用部分:
python
for i in range(1, len(s) + 1):
if self.isP(s[:i]):
self.dfs(s[i:], path + [s[:i]], res)
s[:i]
:表示从字符串s
的第1个字符到第i
个字符形成的子串。path + [s[:i]]
:表示将当前找到的回文子串s[:i]
添加到当前的path
中形成一个新的列表。
三、代码
python
class Solution(object):
def partition(self, s):
"""
:type s: str
:rtype: List[List[str]]
"""
res = []
self.dfs(s, [], res)
return res
def dfs(self, s, path, res):
"""
s: 剩余的字符串
path: 当前分割方案
res: 保存所有分割方案的结果
"""
if not s:
res.append(path)
return
for i in range(1, len(s) + 1):
if self.isP(s[:i]):
self.dfs(s[i:], path+[s[:i]], res)
def isP(self, s):
return s == s[::-1]