18. 子集 II

    xiaoxiao2025-06-07  15

    题目链接:

    https://www.lintcode.com/problem/subsets-ii/description

    给定一个可能具有重复数字的列表,返回其所有可能的子集。

    Example

    样例 1:

    输入:[0] 输出: [ [], [0] ]

    样例 2:

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

    Challenge

    你可以同时用递归与非递归的方式解决么?

    Notice

    子集中的每个元素都是非降序的两个子集间的顺序是无关紧要的解集中不能包含重复子集

    思路:跟17题子集相类似。

              在遍历数组时,判断当前元素是否出现过,没出现过,解法如17题。

               若当前元素出现过,如{1,2,2,2},

               遍历完第0、1个元素后,结果子集res为{{},{1},{2},{1,2}},

               遍历第2个元素时发现,当前元素与第1个元素相等,则将当前加入{2}和{1,2}中变成{2,2}和{1,2,2},加入res,

    res变成{{},{1},{2},{1,2},{2,2},{1,2,2}} 

               遍历第3个元素,遍历res时初始下标变了,res变成{{},{1},{2},{1,2},{2,2},{1,2,2},{2,2,2},{1,2,2,2}} 

     

    代码如下:

    public class Solution {     /**      * @param nums: A set of numbers.      * @return: A list of lists. All valid subsets.      */     public List<List<Integer>> subsetsWithDup(int[] nums) {         // write your code here         List<List<Integer>> res = new ArrayList<>();         res.add(new ArrayList<>());

            Arrays.sort(nums);         int dup = 1;         for(int i=0; i<nums.length; i++) {             if(i-1>=0 &&nums[i]==nums[i-1]) {                 dup ++;             }else{                 dup = 1;             }             int resSize = res.size();             int startIndex = 0;             if(dup>1) {                 startIndex = resSize/dup*(dup-1);             }             for(int j=startIndex; j<resSize; j++) {                 List<Integer> list = new ArrayList<>(res.get(j));                 list.add(nums[i]);                 res.add(list);             }         }         return res;     } }

    最新回复(0)