[回溯法] -- 78 - 子集 - Java + Python

557 阅读1分钟

子集

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

[回溯法] – 39 - 组合总和 - Python + Java

[回溯法] – 40 - 组合总和Ⅱ - Python + Java

[回溯法] – 216 - 组合总和Ⅲ - Python + Java

前面有关组合总和类型的题目需要从给定的数组中找到集合,只是多加了一些限制条件,如长度等于给定的k,或是集合元素之和等于给定的n。而根据本题题目的描述可知,它需要我们找到给定数组中元素能组成的全部子集,只要解集中不含重复的元素即可。

因此,同样使用回溯法从前向后枚举数组,但是保存结果时不加限制,只要选择一次就保存一次,这样就可以找到所有的子集。由于做出选择后,下一次只能从当前位置之后的部分进行选择,且题目说了数组中不含重复元素。因此,最终的解集中自然不会因选择到相同的数字而产生重复结果。

Java解题代码:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> results = new LinkedList<>();
        LinkedList<Integer> track = new LinkedList<>();

        dfs(nums, track, results, 0);
        results.forEach(System.out::println);
        return results;
    }

    private void dfs(int[] nums, LinkedList<Integer> track, List<List<Integer>> results, int start) {
         results.add(new LinkedList<>(track));

        for(int i = start; i < nums.length; i++){
            track.add(nums[i]);
            dfs(nums, track, results, i + 1);
            track.removeLast();
        }
               
    }
}

Python解题代码:

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        if nums == []: return []

        results = []

        def dfs(nums, track):
            results.append(track.copy())
            
            for i in range(len(nums)):            
                track.append(nums[i])
                dfs(nums[i + 1 : ], track)
                track.pop()

        
        dfs(nums, [])
        return results