What is the correct pruning strategy for finding the power set of a list of numbers using DFS?

Question:

Question:

Given an integer array nums that may contain duplicates, return all possible
subsets (the power set).

The solution set must not contain duplicate subsets. Return the solution in any order.

Example 1:
Input: nums = [1,2,2]
Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]

Example 2:
Input: nums = [0]
Output: [[],[0]]

This is my code:

def dfs(nums, result, index, subset):
    result.append(subset.copy())
    if index == len(nums):
        return
    for i in range(index, len(nums)):
        if i > 0 and nums[i] == nums[i - 1]:
            continue
        subset.append(nums[i])
        dfs(nums, result, i + 1, subset)
        subset.pop()

if __name__ == '__main__':
    # nums = [4, 4, 4, 1, 4]
    nums = [1, 2, 2]
    result = []
    dfs(nums, result, 0, [])
    print(result)

I cannot find the correct pruning strategy.

If I input [1,2,2], my output is [[], [1], [1, 2], [2]], so it’s pruning too much.

Asked By: EzjAmeng

||

Answers:

I have made two minor modifications to your code (see comments):

def inList(ls,x):   
# corrects for same sequence of numbers  
# appearing as different element
  for y in ls:
    if sorted(y) == sorted(x):
      return True
  
  return False

def dfs(nums, result, index, subset):
    if not inList(result,subset): # check if new subset is already in power set
      result.append(subset.copy())
    if index == len(nums):
        return
    for i in range(index, len(nums)):
        if i > 0 and nums[i] in nums[index:i - 1]: # avoid adding same number
            continue
        subset.append(nums[i])
        dfs(nums, result, i + 1, subset)
        subset.pop()

if __name__ == '__main__':
    nums = [1, 2, 2, 1, 2]
    result = []
    dfs(nums, result, 0, [])
    print(result) #[[], [1], [1, 2], [1, 2, 2], [1, 2, 2, 1], [1, 2, 2, 1, 2], [1, 2, 2, 2], [1, 2, 1], [1, 1], [2], [2, 2], [2, 2, 2]]
Answered By: Ted Black

This is how I decided to do it to solve the problrm desribed in my question:

def dfs(nums, result, index, subset):
    result.append(subset.copy())
    if index == len(nums):
        return
    for i in range(index, len(nums)):
        if i > index and nums[i] == nums[i - 1]:# it's should "i>index" not "i>0"
            continue
        subset.append(nums[i])
        dfs(nums, result, i + 1, subset)
        subset.pop()


if __name__ == '__main__':
    nums = [4, 4, 4, 1, 4]
    # nums = [1, 2, 2]
    nums.sort()
    result = []
    dfs(nums, result, 0, [])
    print(result)
Answered By: EzjAmeng
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.