【问题标题】:Recursion only generating one pair. What am I doing wrong?递归只生成一对。我究竟做错了什么?
【发布时间】:2019-09-08 02:28:20
【问题描述】:

我正在尝试从输入列表创建排列。我的递归失败,只带回一个列表,应该有多个。 我不确定我的逻辑有什么问题 - 递归新手。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        answer, perm = [], []
        self.dfs(nums, answer, perm)
        return answer

    def dfs(self, nums, answer, perm):
        if not nums:
            answer.append(perm)

        for ind, ele in enumerate(nums):
            perm.append(ele)
            nums.pop(ind)
            self.dfs(nums,answer, perm)

预期:[[1,2,3],[2,1,3],[2,3,1],[1,3,2],[3,1,2],[3,2 ,1]] 实际:[[1,2,3]]

【问题讨论】:

    标签: python python-3.x recursion backtracking


    【解决方案1】:

    注销通过您的解决方案传递的一些数据会很有帮助,这样您就可以准确地看到自己做错了什么。如果我们在代码的每一步都记录numsperm,我们会得到以下信息:

    [1, 2, 3]             # nums 0
    []                    # perm 0
    [2, 3]                # nums 1
    [1]                   # perm 1
    [3]                   # nums 2
    [1, 2]                # perm 2
    []                    # nums 3
    [[1, 2, 3]]           # result
    

    您当前的所有代码都将元素从列表移动到包含原始列表的子列表。您需要在不清空原始列表的情况下跟踪哪些元素已添加到子列表中,然后您可以创建所需的排列。您仍然可以通过递归来完成此操作,但添加 set 的功能将使您的生活变得更轻松。

    这是一个基本示例,您可以根据需要进行调整:

    def dfs(data, perm_out=None):
        if not perm_out:
            perm_out = []
        if not data:
            return [perm_out]
        res = []
        for point in data:
            u = {point}
            diff = data - u
            res += dfs(diff, perm_out + [point])
        return res
    

    在您的简单输入数据上调用它:

    i = [1, 2, 3]
    u = dfs(set(i))
    print(u)
    

    [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
    

    【讨论】:

    • 感谢您的解释 - 您的代码很容易理解。从逻辑上讲,我曾假设迭代将指向对象的副本(idk 为什么我会这样做)。所以我正在改变迭代是有道理的!
    【解决方案2】:

    您的代码的问题在于,它在for 循环的每次迭代中从nums 中删除一个元素,并在nums 被清空后返回答案。所以对于输入[1,2,3],首先将1 附加到permnums 中删除,然后2 相同,然后3,一旦num 为空,perm = [1,2,3]附加到ans 并返回。

    请注意,您可以简单地使用 itertools 中的 permutations() 方法从列表中生成排列:

    import itertools
    
    input_list = [1,2,3]
    permutations = list(itertools.permutations(input_list))
    print(permutations)
    

    输出:

    [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
    

    【讨论】:

      【解决方案3】:

      鉴于您的代码遵循编码挑战中代码问题的格式,我假设您想知道为什么您的解决方案不起作用,而不是使用 python 内置功能的不同解决方案。

      作为参考,您可以分两行执行此操作:

      import itertools
      result = list(itertools.permutations([1, 2, 3]))
      print(result)
      

      lists 工作时的问题是它们都通过指针传递。这是一个递归解决方案。我添加了一些打印件,以便更轻松地查看正在发生的事情。

      class Solution:
          def permutation(self, s):
              # if our list is only one element
              # then nest our list and return it
              if len(s) == 1:
                  return [s]
      
              perm_list = [] # resulting list
              for element in s:
                  # Grab elements other then the one we currently have
                  remaining_elements = [x for x in s if x != element]
      
                  # Permute on the remain elements
                  # a list is returned
                  print("Calling with", remaining_elements)
                  permutations = self.permutation(remaining_elements) # permutations of sublist
      
                  for perm in permutations:
                      # combine our current element with the permuation
                      perm_list.append([element] + perm) 
              print("Returning ", perm_list)
              return perm_list
      

      【讨论】:

      • 这是有道理的——我没有意识到它们是通过指针而不是实际对象传递的。但知道这一点是有道理的。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2018-12-22
      • 2013-08-06
      • 1970-01-01
      • 2016-07-18
      • 2019-12-23
      • 2014-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多