回溯算法实战系列之求子集

696 阅读1分钟

这是我参与更文挑战的第27天,活动详情查看: 更文挑战

这篇文章特意挑选了两道求子集的算法题目,一道是不含重复元素的数组,一道是含有重复元素的数组,都是中等难度的算法题目。是回溯算法应用很经典的一类实例。一起来用回溯算法尝试解决吧。

题目实例Ⅰ

78. 子集

给你一个整数数组 nums ,数组中的元素互不相同。返回该数组所有可能的子集(幂集)。

解集不能包含重复的子集。你可以按任意顺序返回解集。

示例 1:

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

输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

输入:nums = [0]

输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素互不相同

友情链接:leetcode-cn.com/problems/su…

代码实战Ⅰ

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i <= nums.length; i++) {
            backTracking(nums, res, i, 0, new Stack<>());
        }
        return res;
    }

    public void backTracking(int[] nums, List<List<Integer>> res, int length, int index, Stack<Integer> subset) {
        if (subset.size() == length) {
            ArrayList<Integer> list = new ArrayList<>();
            list.addAll(subset);
            res.add(list);
            return;
        }

        for (int i = index; i < nums.length; i++) {
            subset.add(nums[i]);
            backTracking(nums, res, length, i + 1, subset);
            subset.pop();
        }
    }
}

image.png

题目实例Ⅱ

90. 子集 II

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集不能包含重复的子集。返回的解集中,子集可以按任意顺序排列。

示例 1:

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

输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]

示例 2:

输入:nums = [0]

输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10

友情链接:leetcode-cn.com/problems/su…

代码实战Ⅱ

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res=new ArrayList<>();
        boolean[] used=new boolean[nums.length];
        backTracking(nums,res,used,0,new LinkedList<>());
        return res;
    }

    public void backTracking(int[] nums,List<List<Integer>> res,boolean[] used,int index, LinkedList<Integer> path){
        res.add(new LinkedList<>(path));
        if(index>=nums.length){
            return;
        }
        for(int i=index;i<nums.length;i++){
            if(i>0&&!used[i-1]&&nums[i]==nums[i-1]){
                continue;
            }
            used[i]=true;
            path.add(nums[i]);
            backTracking(nums,res,used,i+1,path);
            used[i]=false;
            path.removeLast();
        }
    }
}

image.png