• leetcode-- 90. Subsets II


    1、问题描述

    Given a collection of integers that might contain duplicatesnums, return all possible subsets.

    Note: The solution set must not contain duplicate subsets.

    For example,
    If nums = [1,2,2], a solution is:

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

    2、边界条件:重复数字

    3、思路:组合问题,用递归,但是有重复数字,需要去重,排序后更利于去重。对于一个数字,有两种选择:选或者不选,然后进入下一层递归。

    4、代码实现

    方法一:

    class Solution {
        public List<List<Integer>> subsetsWithDup(int[] nums) {
            List<List<Integer>> results = new ArrayList<>();
            Arrays.sort(nums);
            subsetWithDup(results, new ArrayList<Integer>(), nums, 0);
            return results;
        }
    
        public void subsetWithDup(List<List<Integer>> results, List<Integer> cur,
                                  int[] nums, int index) {
            if (index == nums.length) {//base case index == nums.length
                ArrayList<Integer> result = new ArrayList<>(cur);
                if (!results.contains(result)) { //去重,这种去重的方法不能提高效率,只是事后的手段。
                    results.add(new ArrayList<Integer>(cur));
                }
                return;
            }
    
            subsetWithDup(results, cur, nums, index + 1);
            cur.add(nums[index]);
            subsetWithDup(results, cur, nums, index + 1);
            cur.remove(cur.size() - 1);
        }
    }

    方法二:

    class Solution {
        public List<List<Integer>> subsetsWithDup(int[] nums) {
            List<List<Integer>> results = new ArrayList<>();
            Arrays.sort(nums);
            subsetWithDup(results, new ArrayList<Integer>(), nums, 0);
            return results;
        }
    
        public void subsetWithDup(List<List<Integer>> results, List<Integer> cur,
                                  int[] nums, int index) {
            if (index == nums.length) {//base case index == nums.length
                results.add(new ArrayList<Integer>(cur));
                return;
            }
    
            for (int i = index; i < nums.length; i++) {
                if (i != index && nums[i] == nums[i - 1]) {//去重,这种去重是事前去重,能提高效率。
                    continue;
                }
                cur.add(nums[i]);
                subsetWithDup(results, cur, nums, i + 1);//组合问题这里从i+1开始,排列才从index+1开始
                cur.remove(cur.size() - 1);
            }
            subsetWithDup(results, cur, nums, nums.length);//不要忘记 空集合;也可在前面条件,即
         /*
          for (int i = index; i <= nums.length; i++) {
            if (i == nums.length) {
              subsetWithDup(results, cur, nums, i);
              return;  
            }
          }
         */
    } }

    5、时间复杂度: 空间复杂度:

    6、用到的api:boolean reaults.contains(ArrayList<Integer>)  List<Lsit<Integer>> results 

  • 相关阅读:
    梦断代码阅读笔记一
    进度一
    LOJ#6031. 「雅礼集训 2017 Day1」字符串
    cf700E. Cool Slogans
    BZOJ1014: [JSOI2008]火星人prefix
    BZOJ2716: [Violet 3]天使玩偶
    cf1080F. Katya and Segments Sets
    BZOJ1354: [Baltic2005]Bus Trip
    灭绝树题集
    How Many Substrings?
  • 原文地址:https://www.cnblogs.com/shihuvini/p/7446406.html
Copyright © 2020-2023  润新知