18. Subsets II

Description

Given a list of numbers that may has duplicate numbers, return all possible subsets

 Notice
  • Each element in a subset must be in non-descending order.
  • The ordering between two subsets is free.
  • The solution set must not contain duplicate subsets
Example

If S = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
Solution
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>> results = new ArrayList<>();
        if (nums == null) {
            return results;
        }
        if (nums.length == 0) {
            results.add(new ArrayList<Integer>());
        }
        
        Arrays.sort(nums);      //排序,将重复元素都放在一起
        dfsHelper(0, nums, new ArrayList<Integer>(), results);
        return results;
    }
    //如何去除重复:排序,且按顺序取数,不能间隔取数。如{1, 2(1), 2(2)},规定{1, 2(1)}和{1, 2(2)}重复,不能跳过2(1)取2(2)。程序语言就是,当前数字与前一个数字相同时,前一个数字需要在当前的subset中,不能跳过前一个数字只取当前的数字。
    private void dfsHelper(int startIndex,
                            int[]nums,
                            ArrayList<Integer> subset,
                            List<List<Integer>> results) {
        //deep copy subset & add to results
        results.add(new ArrayList<Integer>(subset));
        for (int i = startIndex; i < nums.length; i++) {
            //判断首先保证i不为0,防止数组越界。前一个数与当前的数相等。前一个数为startIndex - 1当前的数为i且i >= startIndex + 1时,中间至少隔一个数字,此时的情况才出现跳跃取数。
            // if (i != 0 && nums[i] == nums[i - 1] && i > startIndex) {
            if (i != startIndex && nums[i] == nums[i - 1]) {//若i != startIndexs时则i > startIndex,且i一定不为0,因为startIndex最小是0,因此不用单独判断i != 0的情况。
                continue;
            }
            subset.add(nums[i]);
            dfsHelper(i + 1, nums, subset, results);
            subset.remove(subset.size() - 1);
        }
        
    }
}
总结

如何避免重复:

  1. 排序(将重复的元素都放到一起,方便后面判断)
  2. 按顺序取数,不能间隔取数。如{1, 2(1), 2(2)},规定{1, 2(1)}和{1, 2(2)}重复,不能跳过2(1)取2(2)。程序语言就是,当前数字与前一个数字相同时,前一个数字需要在当前的subset中,不能跳过前一个数字只取当前的数字。也就是说,如果有重复的数字,只能按顺序取出,不能有间隔,有了顺序就不会出现重复的情况发生了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Traceback (most recent call last): File "E:\pythonproject\lab1.py", line 49, in <module> import sympy File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\__init__.py", line 51, in <module> from .core import (sympify, SympifyError, cacheit, Basic, Atom, File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\core\__init__.py", line 4, in <module> from .sympify import sympify, SympifyError File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\core\sympify.py", line 9, in <module> from sympy.core.random import choice File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\core\random.py", line 25, in <module> from sympy.utilities.iterables import is_sequence File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\utilities\__init__.py", line 4, in <module> from .iterables import (flatten, group, take, subsets, File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\utilities\iterables.py", line 18, in <module> from sympy.utilities.decorator import deprecated File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\utilities\decorator.py", line 8, in <module> from sympy.testing.runtests import DependencyError, SymPyDocTests, PyTestReporter File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\testing\__init__.py", line 3, in <module> from .runtests import test, doctest File "D:\Anaconda\envs\pythonproject\lib\site-packages\sympy\testing\runtests.py", line 20, in <module> import pdb File "D:\Anaconda\envs\pythonproject\lib\pdb.py", line 74, in <module> import cmd File "D:\Anaconda\envs\pythonproject\lib\cmd.py", line 50, in <module> IDENTCHARS = string.ascii_letters + string.digits + '_' AttributeError: module 'string' has no attribute 'ascii_letters'这是什么错误
最新发布
06-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值