leetcode 78. 子集 题解

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

这题很自然的会想到按照位运算来解题,比如一个数组,含有[1,2,3],也就是长度为3时,一共每一位都有两种可能,有或者没有,那三位的话一共有2^3=8种可能,所有的情况为{000,001,010,011,100,101,110,111},按照这个结果就可以获取到所有不相同的子串了。

思路很简单,但是用到的运算符我也是第一次用,真是惭愧,写这题主要花的时间都是用在理解运算符上了。

首先:

int n = nums.size();        

int all = 1 << n;   

第二句的意思就是对1左移n位,其实得到的结果就是1*2^n=2^n,也就是得出一共有2^n个子集,接下来就是挨个求这些子集了。

还有一个:

(i & (1 << j)) != 0,这句是关键语句,平时我们使用的一般是&&,表示与操作,但是一个&表示的是按照位进行与运算,比如

7&63=7,因为把7和63分别转化成二进制数为000111和111111,按照位相与的话得到的结果就是000111=7,而1<<j的意思则是将1往左移动j位,j从0到n-1,若该数组为[1,2,3],则1<<j分别为001,010,100,再分别和i按位相与,就能得到第i个子集中,哪些位是0,哪些位是1,把为1的对应元素加入到那个子集中。

代码如下:

vector<vector<int>> subsets(vector<int>& nums) {

		int n = nums.size();        
		int all = 1 << n;    //得出共有多少个子集      
		vector<vector<int>> res;    
		for(int i = 0; i < all; i++){             
			vector<int> vec;            
			for(int j = 0; j < nums.size(); j++)
			{                
				if((i & (1 << j)) != 0)  //&表示按位与操作
				{                    
					vec.push_back(nums[j]);                
				}             
			}            
			res.push_back(vec);        
		}        
		return res;
	}

参考博文:https://blog.csdn.net/py13060203/article/details/86763686

猜你喜欢

转载自blog.csdn.net/qq_38279908/article/details/88378563