python 给定一个由不同整数组成的数组nums,返回所有可能的排列,你可以按任何顺序返回答案吗?

kqqjbcuj  于 2023-01-29  发布在  Python
关注(0)|答案(2)|浏览(179)

我正在处理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以避免重复使用数字。
我错过了什么?

ulydmbyx

ulydmbyx1#

以下是回溯版本:

def f(lst, curr = []):
  if len(lst) == len(curr):
    return [tuple(curr)]
  result = []
  for e in lst:
    if e not in curr:
      curr.append(e)
      result.extend(f(lst, curr))
      curr.pop()
  return result

lst = [1, 2, 3, 4]
print(f(lst))
brvekthn

brvekthn2#

输出元组中存在重复1的主要原因(在示例中)是在递归调用中您没有将正确的数字附加到curr。一旦您处于递归调用中,l就 * 已经 * 在curr中!它应该是dfs(curr + str(t), t),因为您已经验证t不在curr中,它应该是附加在它后面的 * 那个 * 号码。
当您进行此更改时,不再需要dfs中的l参数,因为l已不再使用。
然而,还有一些其他问题:

  • return perms有一个错误的缩进(可能是您的问题中的打字错误?)
  • 代码假设数字在转换为字符串时总是单个字符,但代码挑战表明数字可能是10或可能是负数,因此检查数字是否已存在于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设置为数字列表而不是字符串。
下面是应用了上述更改的代码:

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        perms = []
        
        def dfs(curr):
            if len(nums) == len(curr):
                perms.append(curr)
                return
                
            for t in nums:
                if t not in curr:
                    dfs(curr + [t])

        dfs([])
        return perms

在这里使用生成器会很好:

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        def dfs(curr):
            if len(nums) == len(curr):
                yield curr
                return
                
            for t in nums:
                if t not in curr:
                    yield from dfs(curr + [t])

        return list(dfs([]))

最后,当然还有... itertools

import itertools

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        return list(itertools.permutations(nums))

相关问题