一、题目
无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。
示例1:
输入:S = "qwe"
输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"]
示例2:
输入:S = "ab"
输出:["ab", "ba"]
二、DFS
dfs(当前状态):
if 当前状态 == 目的状态
return...
else:for 循环遍历新状态:
if 状态合法:
ans[记录该状态]record[该状态已被记录]
dfs(新状态)
record[恢复空白记录]
三、代码
class Solution:
def permutation(self, S: str) -> List[str]:
res = [] # 用于输出结果
ans = [0] * len(S) # 每次得到的一个结果
record = [False] * len(S) # 每个字母在排序时是否用过
def dfs(i:int):
if i == len(S):
res.append(''.join(ans)) # 使用join可以完美转换列表和字符串!
else:
for j in range(len(S)): # 将第j个字符试图插入ans中的第i位
if not record[j]: # 第j个字符没用过,所以可插
ans[i] = S[j] # ans的第i位就决定使用S的第j个字符了
record[j] = True # 第j个字符用过了,True
dfs(i + 1) # 决定ans的第i+1位用哪个字符
record[j] = False # 第i位使用第j个字符的所有情况都遍历完成后,取消第j个字符使用过的标记
dfs(0)
return res
四、注意问题
1. 使用递归时返回值为None:
class Solution:
def permutation(self, S: str) -> List[str]:
ans = [0] * len(S)
record = [False] * len(S)
def dfs(i:int):
if i == len(S):
return ''.join(ans)
else:
for j in range(len(S)):
if not record[j]:
ans[i] = S[j]
record[j] = True
dfs(i + 1)
record[j] = False
return dfs(0)
想使用dfs直接return出排列好的每一次的ans,但是返回值一直是none,ans并非没有排列。
此处是由于在函数dfs中,并非在函数递归执行到最后一步return时才返回我们需要的值,而是在第一次调用递归函数时,虽然函数进入到了else分支,执行dfs(i+1)语句,但此时仍会返回一个值,默认值即为None。
一个函数中必须在每一种分支都有return,保证各种情况下的函数都能返回值,因此解决此处的问题可以将dfs(i+1)改为 return dfs(i+1)。
但这样导致函数在完成第一次排序后就会return得到的值,结束dfs过程,因此dfs函数不能这样处理。
2.将列表转换为字符串
使用str()直接转换列表会导致得到的字符串中包括列表的中括号以及列表中的引号逗号等,不能算作真正的转换为了字符串。
使用join():
' * '.join(list):使用某种字符(此处为*)将列表list中的所有元素连接起来得到一个字符串,因此我们可以使用 ''.join() 来无缝连接每个元素,实现列表与字符串的完美转换。