LeetCode——90. 子集 II(Subsets II)[中等]——分析及代码(Java)

LeetCode——90. 子集 II[Subsets II][中等]——分析及代码[Java]

一、题目

给你一个整数数组 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)
链接:https://leetcode-cn.com/problems/subsets-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、分析及代码

1. 回溯法

(1)思路

结合回溯法求所有子集,对于连续的 range 个重复元素,在指针后移 range 位的同时依次选取 0 - range 个数字,避免子集重复。

(2)代码

class Solution {
    
    
    List<List<Integer>> ans;//解集

    public List<List<Integer>> subsetsWithDup(int[] nums) {
    
    
        ans = new ArrayList<List<Integer>>();
        Arrays.sort(nums);//排序,使重复元素相邻
        List<Integer> list = new ArrayList<Integer>();
        subSet(nums, list, 0);
        return ans;
    }

    //回溯法求所有子集
    public void subSet(int[] nums, List<Integer> list, int i) {
    
    
        if (i == nums.length) {
    
    //遍历完nums,将当前数列加入解集
            ans.add(new ArrayList<Integer>(list));
            return;     
        }
        int range = 1;//计算重复元素范围
        while (i + range < nums.length && nums[i + range] == nums[i])
            range++;
        //在当前重复元素中,依次取0-range个元素
        subSet(nums, list, i + range);
        for (int j = 0; j < range; j++) {
    
    
            list.add(nums[i]);
            subSet(nums, list, i + range);
        }
        for (int j = 0; j < range; j++)//恢复数列
            list.remove(list.size() - 1);
        return;
    }
}

(3)结果

执行用时 :1 ms,在所有 Java 提交中击败了 100.00% 的用户;
内存消耗 :38.6 MB,在所有 Java 提交中击败了 76.22% 的用户。

三、其他

暂无。

猜你喜欢

转载自blog.csdn.net/zml66666/article/details/115351664