LeetCode 78. Subsets(子集)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/princexiexiaofeng/article/details/79645760

题目描述:

    Given a set of distinct integers, nums, return all possible subsets (the power set).
    Note: The solution set must not contain duplicate subsets.
    For example, if nums = [1,2,3], a solution is:

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

分析:
    题意:给定一个整型数组集合,返回它的所有不重复子集。
    思路:这道题考察运用位运算来进行集合运算。我们采用规则可以解决本题。

    在程序中表示集合的方法有很多种,当元素个数比较少时,用二进制来表示比较方便。集合{0, 1, 2, ... , n - 1}的子集S可以用如下方式编码:

LeetCode 78

    借此机会,我统一介绍一下基本的集合运算操作。
    ① 空集∅:0
    ② 只含有第i个元素的集合{i}:1 << i
    ③ 含有全部你个元素的集合{0, 1, 2, ... , n - 1}:(1 << n) - 1
    ④ 判断第i个元素是否属于集合S:if ( S >> i & 1)
    ⑤ 向集合中加入第i个元素(S∪{i}):S | 1 << i
    ⑥ 从集合中去除第i个元素(S \ {i}):S & ~(1 << i)
    ⑦ 集合ST的并集:S | T
    ⑧ 集合ST的交集:S & T
    ⑨ 枚举某个集合sup的子集:这里sup是一个二进制码,其本身也是某个集合的子集。例如给定了01101101这样的集合,要将01100000或者00101101等子集枚举出来。此时sub + 1并不一定时sup的子集。而(sub + 1) & sup虽然是sup的子集,可是很有可能依旧是sub,没有改变。

        因此我们反过来计算,从sup开始每次减1直到0为止。由于sub - 1并不一定是sup的子集,所以我们把它与sup进行按位与&,可以将sup所有的子集按照降序列举出来。

int sub = sup;
do {
	sub = (sub - 1) & sup;
} while(sub != sup);

    ⑩ 枚举集合{0, 1, 2, ... , n - 1}所包含的所有大小为k的子集的方法:

int comb = (1 << k) - 1;
while (comb < 1 << n) {
	int x = comb & -comb, y = comb + x;
	comb = ((comb & ~y) / x >> 1) | y;
}

代码:

#include <bits/stdc++.h>

using namespace std;

/*
	int sub = sup;
	do{
		sub = (sub - 1) & sup;
	}while(sub != sup);
*/
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
		vector<vector<int>> ans;
		int n = nums.size();
		if (n == 0) {
			return ans;
		}
        int sup = 0;
		int min_e = INT_MAX, max_e = INT_MIN;
		for (int i = 0; i <= n - 1; i++) {
			sup += (1 << nums[i]);
			min_e = min(min_e, nums[i]);
			max_e = max(max_e, nums[i]);
		}
		int sub = sup;
		do {
			vector<int> res;
			for (int i = min_e; i <= max_e; i++) {
				if (sub & (1 << i)) {
					res.push_back(i);
				}
			}
			ans.push_back(res);
			sub = (sub - 1) & sup;
		} while(sub != sup);
		return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/princexiexiaofeng/article/details/79645760