Leetcode78—Subset

Given a set of integer array  nums without repeated elements , return all possible subsets (power sets) of the array.

Note: The solution set cannot contain duplicate subsets.

Examples:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1, 2],
  []
]

 Method 1: Backtracking

The backtracking method is a search algorithm, the purpose is to find all conditions that meet the conditions, and its characteristic is that it will return, so that it can get all the conditions.

In many recursive problems, the method we take is to exhaust all possibilities to find a legal solution. However, in some cases, when recursive to a certain layer, according to the set judgment conditions , it can be judged that this solution is illegal. In this case, we no longer need to perform deep recursion, which can improve the efficiency of the algorithm. This kind of algorithm is called " backtracking method ", and the judgment condition set is called " pruning function ".

It can be roughly divided into such cases, and search in order according to the red line:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> out;//保存最终结果
        vector<int>curout;//存储子集
        generate(nums, out, curout, 0); 
        return out;
    }
    

    void generate(vector<int> nums, vector<vector<int>> &out, vector<int>&curout, int k)
    {
	    if (k >= nums.size())//当循环到底时推出,k可表示循环深度
	    {
		    return;
	    }
	    curout.push_back(nums[k]);
        out.push_back(curout);
	    generate(nums, out, curout, k + 1);//对存在的子集
	    curout.pop_back();//向后退一步
	    generate(nums, out, curout, k + 1);
    }
};

Looking at the topic comment, a big guy puts forward the method of bit arithmetic, and thinks it is magical.

In fact, looking for the subset of [1,2,3] can consider each number, each number has two states, in the subset or not in the subset. Use bitwise AND to find this bit.

	class Solution {
	public:
		vector<vector<int>> subsets(vector<int>& nums) {
			vector<vector<int>> out;//保存最终结果
            vector<vector<int>> out;
	        int n = nums.size();
	        int a = 1 << n;//子集的数量
	        for (int i = 0; i < a; i++)
	        {
		        vector<int> item;
		        for (int j = 0; j < n; j++)
		        {
			        if (i&(1 << j))//&位与运算,只有j位和i的1一致时为真
			        {
				        item.push_back(nums[j]);
			        }
		        }
		    out.push_back(item);
	        }
	        return out;
    }
};

 

Published 17 original articles · liked 0 · views 3228

Guess you like

Origin blog.csdn.net/qq_31874075/article/details/103446390