LeetCode(90)-SubsetII

版权声明:XiangYida https://blog.csdn.net/qq_36781505/article/details/83583945

90-Subset II

Given a collection of integers that might contain duplicates, nums, return all
possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
Input: [1,2,2]
Output:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]

这个题目就是说给你一个数组,然后求出他们的子集,最开始以为这个题很简单,思路很快就出来了,但是总是不能Accept,或者我用循环不断的组合然后判断是否重复导致超时。
然后想到了另一种思路

  • 1、先排序,排序是很必要的,这样你就知道数组的重复的地方在哪儿了。
  • 2、将数组中的数一个一个的放入容器,每放一个,这一个与容器原来的元素组合。
  • 3、比较关键的地方就是,重复的数字怎么处理,比如,题目给的1,2,2,我们来模拟一下思路的过程
    • 先放入空,此时容器大小为1
    • 数组中拿出1,与空相组后放入容器,此时容器的大小为2里面是[[],[1]]
    • 数组中拿出2,与空组合后是[2],与[1]组合后是[1,2]此时容器的大小是4,里面的元素是[[],[1],[2],[1,2]]
    • 然后是拿出数组的最后一个数2,通过nums[i]==nums[i-1]检测到与上一个数重复了,那是不是不需要这个数去组合了?当然不是,只是不能与上一个2组合过的元素组合,所以我们就记录每次组合后容器的位置index,下次若遇到重复的,就重index位置开始组合就行了。

具体看代码吧,多调试几遍就懂了

public List<List<Integer>> subsetsWithDup(int[] nums) {
       Arrays.sort(nums);
       List<List<Integer>>lists=new LinkedList<>();
       lists.add(new LinkedList<>());
       int size=lists.size();
       //nums[i]数组中的每个元素
       int index=0;
       for (int i = 0; i <nums.length; i++) {
           //与链表中的每个元素相组合
           int j=0;
           if(i!=0&&nums[i]==nums[i-1])j=index;
           for (; j <size; j++) {
              List list=new LinkedList(lists.get(j));
              list.add(nums[i]);
              lists.add(list);
           }
           index=size;//记录上次的位置
           size=lists.size();
       }
       return lists;
   }

这里涉及到一个关键的地方,关于浅拷贝与深拷贝的问题,第二层循环里面若是

List list=lists.get(j);

这样返回的只是地址,也就是你改动的全是一个地址块,这样的话,输出的全是这样

[[1, 2, 2, 2, 2], [1, 2, 2, 2, 2], [1, 2, 2, 2, 2], [1, 2, 2, 2, 2], [1, 2, 2, 2, 2], [1, 2, 2, 2, 2]]

在这里插入图片描述

呐~,容器里面每个元素的地址都是一样的呢

猜你喜欢

转载自blog.csdn.net/qq_36781505/article/details/83583945
今日推荐