zoukankan      html  css  js  c++  java
  • Subsets II

    题目链接

    Subsets II - LeetCode

    注意点

    • 有重复的数字
    • 数组可能是无序的,要先排序

    解法

    解法一:递归,只需要在Subsets中递归写法的基础上多加一句if(find(ret.begin(),ret.end(),tmp) == ret.end()) ret.push_back(tmp);j即可,因为已经排序了,所以加进去的如果已经存在就说明是重复的。

    class Solution {
    public:
        typedef vector<int> v;
        void recursion(int start,v nums,v tmp, vector<v>& ret)
        {
            if(find(ret.begin(),ret.end(),tmp) == ret.end()) ret.push_back(tmp);
            int n = nums.size();
            for(int i = start;i < n;i++)
            {
                tmp.push_back(nums[i]);
                recursion(i+1,nums,tmp,ret);
                tmp.pop_back();
            }
        }
        vector<vector<int>> subsetsWithDup(vector<int>& nums) {
            sort(nums.begin(),nums.end());
            vector<vector<int>> ret;
            v tmp;
            recursion(0,nums,tmp,ret);
            return ret;
        }
    };
    


    解法二:递归。只需要在Subsets中递归写法的基础上多加一句while(i+1 < n && nums[i] == nums[i+1]) i++;即可,这句话的作用就是把下图中树结点为X的剪枝。

                            []        
                       /                  
                      /                 
                     /              
                  [1]                []
               /                  /    
              /                  /              
           [1 2]       [1]       [2]     []
          /          /        /       / 
      [1 2 2] [1 2]  X   [1]  [2 2] [2] X  []
    
    class Solution {
    public:
        typedef vector<int> v;
        void recursion(int start,v nums,v tmp, vector<v>& ret)
        {
            ret.push_back(tmp);
            int n = nums.size();
            for(int i = start;i < n;i++)
            {
                tmp.push_back(nums[i]);
                recursion(i+1,nums,tmp,ret);
                tmp.pop_back();
                while(i+1 < n && nums[i] == nums[i+1]) i++;
            }
        }
        vector<vector<int>> subsetsWithDup(vector<int>& nums) {
            sort(nums.begin(),nums.end());
            vector<vector<int>> ret;
            v tmp;
            recursion(0,nums,tmp,ret);
            return ret;
        }
    };
    

    解法三:非递归。在Subsets中非递归写法的基础上进行修改,如果当前数字和上一次循环的数字一样,那么就只能在上一次循环产生的集合后面追加当前数字,而不能在所有集合后面追加

    class Solution {
    public:
        vector<vector<int>> subsetsWithDup(vector<int>& nums) {
            if(nums.empty()) return {};
            sort(nums.begin(),nums.end());
            vector<vector<int>> ret(1);
            int i,j,n = nums.size(),last = nums[0],lastSize = 1;
            for(i = 0;i < n;i++)
            {
                if(last != nums[i])
                {
                    last = nums[i];
                    lastSize = ret.size();
                }
                int m = ret.size();
                for(j  = m-lastSize;j < m;j++)
                {
                    ret.push_back(ret[j]);
                    ret.back().push_back(nums[i]);
                }
            }
            return ret;
        }
    };
    

    小结

  • 相关阅读:
    nodejs 访问mysql
    1.移动的矩形
    ubuntu 16.04 搜狗输入法无法中英文切换
    修改可选项文件实现自动连接数据库服务器
    Codeforces Round #374 (Div. 2)解题报告
    hihoCoder 1238 : Total Highway Distance(dfs + 二分)
    AIM Tech Round 3 (Div. 2) 题解
    Codeforces Round #367 (Div. 2) 题解
    图论模板集合
    poj1144Network (求割点模板题)
  • 原文地址:https://www.cnblogs.com/multhree/p/10523567.html
Copyright © 2011-2022 走看看