LeetCode78/90 subset I/II

一:subset I

题目:

Given a set of distinct integers, S, return all possible subsets.

Note:

  • Elements in a subset must be in non-descending order.
  • The solution set must not contain duplicate subsets.

For example,

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

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

链接:https://leetcode.com/problems/subsets/

分析:说白了就是求不同元素所构成的所有子集,这里提供三种方法

(1)递归————较难理解

对结合[1,2,3] 从0结点的1开始,都有选择或者不选,不选为空,放在左子树,选择放在由子树,这样就得到一棵完全二叉树,其中叶子结点就是我们所求。理解代码可以试着从只有1个结点开始思考。

图中与代码有差异,左右刚好相反

class Solution {
public:
    void recursion(vector<int> temp, vector<int> &S, int level, vector<vector<int> > &result){
        if(level == S.size()){
            result.push_back(temp);
            return;
        }
        recursion(temp, S, level+1, result);   // 不选元素s[level]  通过只有1个元素来理解递归
        temp.push_back(S[level]);
        recursion(temp, S, level+1, result);   // 选择元素s[level]
    }
    vector<vector<int> > subsets(vector<int> &S) {
        sort(S.begin(), S.end());
        vector<int> temp;
        vector<vector<int> > result;
        recursion(temp, S, 0, result);
        return result;
    }
};

(2) 迭代

通过上图我们可以看出,每次都是在原有的子集后面添加新元素S[i] 并加入到result中就会得到另外一个子集,因此可以采用迭代处理。

class Solution {
public:
    void iterSet(int i, vector<vector<int> > &result, vector<int> &S){
        int n = result.size();
        for(int j = 0; j < n; j++){
            vector<int> temp = result[j];   //集合中原有的子集保持不变,
            temp.push_back(i);             //但是对于每个子集都新遍历的一个元素S[i]加入构成新子集
            result.push_back(temp);
        }
    }
    vector<vector<int> > subsets(vector<int> &S) {
        vector<vector<int> > result;
        sort(S.begin(), S.end());
        vector<int> temp;
        result.push_back(temp);    // 集合中已有空集
        for(int i = 0; i < S.size(); i++){       // 对于每个元素都遍历一遍,
            iterSet(S[i], result, S);
        }
        return result;

    }
};

(3)位操作

对于n个元素,每个元素要么加入要么不加入,则会得到一个n位的二进制串,n为二进制串可以看做是一个状态或者说一个子集,每个元素与一位一一对应,状态的大小为1<<n. 对于每个状态j,我们通过判断第k位是否为1,为1则将S[k]加入vec,判断结束,将vec加入result即可。

class Solution {
public:
    vector<vector<int> > subsets(vector<int> &S) {
        vector<vector<int> > result;
        int n = S.size();
        int max = 1 << n;     // 最多状态数 存在用1 不存在用0
        int i = 0;
        sort(S.begin(), S.end());
        while(i < max){            // 对每一种状态进行遍历 并将其所对应的元素加入到集合中
            int j = i;
            vector<int> temp;
            /*for(int k= 0; k < n; k++){
                if((j & (1<<k)) != 0) temp.push_back(S[k]);
            }*/
            int index = 0;
            while(j>0){
                if(j&1) temp.push_back(S[index]);    // 第index为1 则加入s[index]位
                j = j >> 1;
                index++;
            }
            result.push_back(temp);
            i++;
        }
        return result;

    }
};

二:subset II

题目:

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

Note:

  • Elements in a subset must be in non-descending order.
  • The solution set must not contain duplicate subsets.

For example,

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

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

链接:https://leetcode.com/problems/subsets-ii/

分析:与unique paths的区别在于允许元素重复,这是当元素重复时,我们会发现每次加入的子集都是上次迭代的子集,因此需要对迭代法略做改进。

class Solution {
public:
    void iterSet(int i, vector<vector<int> > &result, vector<int> &S, int &t){
        int n = result.size();
		int count = 0;
		int j = 0;
		if(i-1>=0 && S[i]==S[i-1])j = n-t;   // 如果相等  则只能在上次加入的子集中加入s[i]
        for(;j < n; j++){
            vector<int> temp = result[j];   //集合中原有的子集保持不变,
			temp.push_back(S[i]);             //但是对于每个子集都新遍历的一个元素S[i]加入构成新子集
            result.push_back(temp);
			count++;                     //主要用来记录每次迭代加入集合个数
        }
		t = count;
    }
    vector<vector<int> > subsetsWithDup(vector<int> &S) {
        vector<vector<int> > result;
        sort(S.begin(), S.end());
        vector<int> temp;
        result.push_back(temp);    // 集合中已有空集
		int t = 0;
        for(int i = 0; i < S.size(); i++){       // 对于每个元素都遍历一遍,
			//if(i-1 < 0 || S[i] != S[i-1]) t = 0;
            iterSet(i, result, S, t);
        }
        return result;
    }
};
时间: 2024-11-02 05:39:53

LeetCode78/90 subset I/II的相关文章

Leetcode 78. Subsets (backtracking) 90 subset

using prev class Solution { List<List<Integer>> res = new ArrayList<List<Integer>>(); public List<List<Integer>> subsets(int[] nums) { List<Integer> temp = new ArrayList<>(); back(temp,nums, 0); return res;

LeetCode 90:Subsets II

Given a collection of integers that might contain duplicates, nums, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If nums = [1,2,2], a soluti

&amp;lt;LeetCode OJ&amp;gt; 78 / 90 Subsets (I / II)

Given a set of distinct integers, nums, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If nums = [1,2,3], a solution is: [ [3], [1], [2], [1,2

leetcode || 90、Subsets II

problem: Given a collection of integers that might contain duplicates, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,2], a sol

【leetcode78】Single Number II

题目描述: 给定一个数组,里面除了一个数字,其他的都出现三次.求出这个数字 原文描述: Given an array of integers, every element appears three times except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra m

R子集subset

> x<-c(6,1,2,3,NA,12) > x[x>5]    #x[5]是未知的,因此其值是否大于5也是未知的 [1]  6 NA 12 > subset(x,x>5)  #subset直接会把NA移除 [1]  6 12 > subset(airquality, Temp > 80, select = c(Ozone, Temp)) Ozone Temp 29     45   81 35     NA   84 36     NA   85 38 

Pascal编译器大全(非常难得)

http://www.pascaland.org/pascall.htm Some titles (french) : Compilateurs Pascal avec sources = compiler with sourcesComposants pour Delphi = Components for DelphiCompilateurs pour autres langages avec sources en pascal = Compilers for other languages

LeetCode Problems List 题目汇总

No. Title Level Rate 1 Two Sum Medium 17.70% 2 Add Two Numbers Medium 21.10% 3 Longest Substring Without Repeating Characters Medium 20.60% 4 Median of Two Sorted Arrays Hard 17.40% 5 Longest Palindromic Substring Medium 20.70% 6 ZigZag Conversion Ea

编译原理的一些练习题

这里收集了sicily的陈炬桦老师编译原理实验课程的题目,曝上代码以供参考. (如果这里的代码对您的思路有些许启发的话,请您点击一下推荐,给予作者写作的鼓励,不胜感谢!) 1-词法分析 题目1000: 1 1000. 词法分析程序设计 2 总提交数量: 183 通过数量: 138 3 4 时间限制:1秒 内存限制:256兆 5 题目描述 6 设一语言的关键词.运算符.分界符的个数与单词如下: 7 struct { int number; string str[10]; } keywords={3