zoukankan      html  css  js  c++  java
  • Leetcode每日一题 90.子集 II

    90. 子集 II

    给你一个整数数组 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

    本题用回溯算法比较容易理解

    class Solution {
    public:
        vector<vector<int>> res;
        vector<int> sub;
        int size;
    public:
        void back(vector<int>& nums,int start)
        {
            res.push_back(sub);
            for(int i = start ; i < size ; i++)
            {
                if(i > start && nums[i] == nums[i-1])
                    continue;
                sub.push_back(nums[i]);
                back(nums,i+1);
                sub.pop_back();
            }
        }
    public:
        vector<vector<int>> subsetsWithDup(vector<int>& nums) {
           res.clear();
           sub.clear();
           this->size = nums.size();
           sort(nums.begin(),nums.end());
           back(nums,0);
    
           return res;
        }
    };
    

    首先将nums排序,因为这样才能达到去重的目的,后面说。
    start是每次组合的首地址,直接看循环,分析if为什么这样写


    设置i>start是为了防止第一次循环就判断nums[i] == nums[i-1],这不是我们要判断的范围,因为i==start时,明显我们只有一个元素进来。
    nums[i] == nums[i-1] 是为了去重,有点不好解释,我们就这样想象,举个例子[1,2,3,3],start是0的时候我们从1进入,然后递归进入back(),不管它子递归的循环,我们就只看第一次递归的循环,是不是会得到[1,2,3,3],你们可能会说,你不是设置了nums[i] == nums[i-1]就continue吗,为什么会得到[1,2,3,3],这就是因为前面有个i>start,但如果我们在子循环时,也就是此时sub里面有[1,2]时的递归层,我们遍历到第一个3,加进去sub = [1,2,3],此时i明显已经大于start,我们不会再得到第二个[1,2,3],此时这个3是第4个3.


    用一个非常妙的解释方法就是,把整个结构想象成一个树,层相同是不允许的,树枝相同是允许的。

    i > start && nums[i] == nums[i-1]就诠释了这种判断。

  • 相关阅读:
    C# 常用函数和方法集
    CSS选择器、优先级和匹配原理
    都是王安石惹的祸?
    世界上的一类
    历史之不可理喻片段
    历史惊人的相似
    20世纪鲜为人知的军事巨灾
    unity制作简单血条
    Unity中Instantiate物体失效问题
    Unity3D实现DoubleClick的一种方法
  • 原文地址:https://www.cnblogs.com/xiangqi/p/14604461.html
Copyright © 2011-2022 走看看