【问题标题】:How to return the list of all the Subset of a list of integer, using Python?如何使用Python返回整数列表的所有子集的列表?
【发布时间】:2020-03-20 06:37:51
【问题描述】:

我得到了一个整数数组 A,我需要返回一个包含它所有子集的数组。 我已经尝试使用回溯来解决这个问题。

def subset_helper(index, result, A, temp):
    result.append(temp)
    #print(temp)
    for i in range(index,len(A)):
        temp.append(A[i])
        subset_helper(i+1,result,A,temp)
        #backtracking
        temp.pop()
    return    
def subsets(A):
    result = []
    temp = []
    index = 0
    subset_helper(index, result, A, temp)
    return result

这会返回一个空列表。打印 temp 给了我正确的答案,但问题要求我返回一个数组。我猜由于 按引用调用 导致的临时数组在每次迭代中都会发生变化,这可能是它给我一个空列表列表的原因。

Input : [12,13]
Expected Output : [[],[12],[12,13],[13]]
My Output : [[],[],[],[]]

【问题讨论】:

    标签: python pass-by-reference backtracking


    【解决方案1】:

    您可以使用 powerset 来获得您正在寻找的输出。

    iterable=[12,13]
    res=list(powerset(iterable))
    
    

    【讨论】:

      【解决方案2】:

      你可以尝试在subset_helper中打印地址, 你会发现你的 temp 是同一个对象地址, 这就是为什么您的结果是相同对象值的列表:

      def subset_helper(index, result, A, temp):
          result.append(temp)
          print(id(temp))
          for i in range(index,len(A)):
              temp.append(A[i])
              subset_helper(i+1,result,A,temp)
              #backtracking
              temp.pop()
          return  
      

      输出:

      1559293711304
      1559293711304
      1559293711304
      1559293711304
      [[], [], [], []]
      

      现在,更改附加 tmp 对象的副本:

      import copy
      def subset_helper(index, result, A, temp):
          result.append(copy.copy(temp))
          for i in range(index,len(A)):
              temp.append(A[i])
              subset_helper(i+1,result,A,temp)
              #backtracking
              temp.pop()
          return    
      

      现在您将一个新对象附加到结果列表中, 您可以看到预期的输出:

      [[], [12], [12, 13], [13]]
      

      【讨论】:

        【解决方案3】:

        如果不是作业问题,可以使用优秀的itertools模块生成子集

        from itertools import combinations, chain
        
        def get_subsets(integers):
            return list(chain.from_iterable([combinations(integers, i) for i in range(len(integers) + 1)]))
        
        Input: get_subsets([1, 2, 3])
        Output: [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
        

        【讨论】:

          【解决方案4】:

          此外,从算法的角度来看,您可以遍历所有可能的二进制数,最多为 2**N(N 是您的集合的长度),并取 1 表示该元素应属于子集:

          A = ["A", "B", "C"]
          
          allSubsets = []
          for i in range(2**len(A)):
            n = 1
            subset = []
            for j in range(len(A)):
              if i & n != 0:
                subset.append(A[j])
              n <<= 1
            allSubsets.append(subset)
          
          print(allSubsets)
          

          产生:

          [[], ['A'], ['B'], ['A', 'B'], ['C'], ['A', 'C'], ['B', 'C'], ['A', 'B', 'C']]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多