我正在处理LeetCode问题46. Permutations:
给定一个由不同整数组成的数组nums
,返回 * 所有可能的排列 *。你可以以任何顺序返回答案。
我想用回溯来解决这个问题,我的想法是把这个问题想象成一棵二叉树,然后沿着一条路径前进,当我到达一个叶子时,我弹出visit
数组,并恢复到一个新的根编号。
我的代码如下:
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
perms = []
def dfs(curr, l):
if len(nums) == len(curr):
perms.append([int(i) for i in curr])
return
visit = []
for t in nums:
if str(t) not in curr:
visit.append(t)
dfs(curr + str(l), t)
visit.pop()
return
dfs('', nums[0])
return perms
以下测试用例的输出错误:
nums = [1,2,3]
预期输出为:
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
但是我的代码输出:
[[1,1,2],[1,1,2],[1,1,3],[1,1,3],[1,2,2],[1,2,3],[1,3,2],[1,3,3]]
我不明白为什么我的输出中有重复的列表,尽管我检查了str(t) not in curr
以避免重复使用数字。
我错过了什么?
2条答案
按热度按时间ulydmbyx1#
以下是回溯版本:
brvekthn2#
输出元组中存在重复
1
的主要原因(在示例中)是在递归调用中您没有将正确的数字附加到curr
。一旦您处于递归调用中,l
就 * 已经 * 在curr
中!它应该是dfs(curr + str(t), t)
,因为您已经验证t
不在curr
中,它应该是附加在它后面的 * 那个 * 号码。当您进行此更改时,不再需要
dfs
中的l
参数,因为l
已不再使用。然而,还有一些其他问题:
return perms
有一个错误的缩进(可能是您的问题中的打字错误?)curr
中的方法将不可靠。例如,如果您首先访问“10”,然后想访问“1”,则它将不起作用,因为if str(t) not in curr:
将不为真。其次,
[int(i) for i in curr]
只提取一位数,如果在curr
中附加了一个负数,则[int(i) for i in curr]
将失败,因为int('-')
将引发异常。没问题,但是
visited
列表在你的代码中是无用的。它从来没有被用来验证任何东西。而且return
作为dfs
中的最后一条语句也不是真的需要,因为这是默认的行为。我建议将
curr
设置为数字列表而不是字符串。下面是应用了上述更改的代码:
在这里使用生成器会很好:
最后,当然还有...
itertools
: