返回给定列表的所有可能的子集会返回错误的答案

时间:2019-01-12 10:23:11

标签: python recursion backtracking

我目前正在练习一个面试问题,并且在其中必须返回给定列表的所有可能子集。

例如

Input: [1,2,2]
Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

是答案。

class Solution(object):
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        subset = []
        self.backtrack(sorted(nums), res, subset, 0)
        return res

    def backtrack(self, nums, res, subset, start):
        res.append(list(subset))
        for i in range(start, len(nums)):
            if i > start and nums[i] == nums[i - 1]:
                continue
            subset.append(nums[i])
            self.backtrack(nums, res, subset, start + 1)
            subset.pop()

我的解决方案如上所述,使用回溯。我检查了条件if i > start and nums[i] == nums[i - 1]以处理重复项。但是,我的输出是[[],[1],[1,2],[1,2,2],[2],[2,2],[2,2,2]],给出了不应生成的额外[2, 2, 2]

我按照自己的代码绘制了一个图,但是仍然不明白为什么会生成此图。它不是应该在那之前终止吗?

谢谢

1 个答案:

答案 0 :(得分:1)

isValidSubset 函数在num到子集之间进行子构造,因此对于  [1,2,2] - [2,2,2]保持2并希望成为有效子集

def subsetsWithDup(nums):
    res = []
    subset = []
    backtrack(sorted(nums), res, subset, 0)
    return res


def isValidSubset(s, n):
    nums = s.copy()
    subset = n.copy()
    return len([i for i in nums if not i in subset or subset.remove(i)]) == 0


def backtrack(nums, res, subset, start):
    if (isValidSubset(subset, nums)):
        res.append(list(subset))
    for i in range(start, len(nums)):
        if i > start and nums[i] == nums[i - 1]:
            continue
        subset.append(nums[i])
        backtrack(nums, res, subset, start + 1)
        subset.pop()


a = [1, 2, 2]
b = [2, 2, 2]

print(subsetsWithDup(a))