Subsets

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,3],
  [1,3],
  [2,3],
  [1,2],
  []
] 这是一道求一个给定集合所有子集的问题,其核心问题在于如何遍历整个子集。

   对于这道题目我的思路是一个straightforward的方法即: 根据子集元素个数进行遍历(0~nums.size()),在每一种子集下面对固定长度(假设为n)的子集,我们可以固定前n-1个元素,激活第n个元素遍历,再固定前n-2个元素,后面两个激活进行遍历。。。。最后,当遍历完整个长度区间的时候我们就得到了该集合的所有子集。 无奈,得出子集的输出顺序与leetcode的测试用例不同,无奈过不了。不过正因为如此,我学习到了两种求子集的方法。

1、回溯法:  采用递归的方式实现
 1 const int n = 4;
 2 int x[n];
 3 //回溯法
 4 void backtrack(int t)
 5 {
 6     if(t >= n)
 7     {
 8         for(int i = 0; i < n; i++)
 9             cout<<x[i];
10         cout<<endl;
11     }
12     else
13     {
14         for(int i = 0; i <= 1; i++)
15         {
16             x[t] = i;//针对每一个元素进行判断,1表示该元素存在于该子集中,0表示不存在
17             backtrack(t + 1);
18         }
19     }
20 }

    通过对每一个元素的存在与否进行回溯,很容易就遍历了整个集合。

    这段代码核心就是14~18行,我们可以看到当第一次进入时,即从主线程中调用 backtrack(0),程序会执行到14行,这里有两个分支,分别是x[0]=0;x[0]=1;按照程序执行的顺序来看不是并发的。不过在逻辑上是这么执行的。

好了现在到下一个判断(由于t<n,所以第一个if不生效),此时第一个分支执行又会派生出两个分支,分别是x[1]=0,x[1]=1,同样,第一个分支的另一部分也会派生出两个分支,于是我们得到以下组合{x[0],x[1]} = {0,0} or {0,1} or {1,0} or {1,1}。

此时很明显对前两个元素的所有组合做了一个遍历,按照这种结构继续递归,最后(t==n),我们将会对所有的元素子集做出一个遍历(其实就是利用了二叉树的结构,所有的叶子就是我们要的结果)。

2、位运算法

    这个方法直接遍历整个子集,没有递归,故运算速度快于第一种。这是某位博主在topcoder上面看到的。我们就时以长技以自强咯。

    整个遍历的思想是很简单的:

    该算法包含两个循环:

    第一重循环是枚举所有子集,共2^n个,即1 << n个
    第二重循环求集合所有j个元素的值,0或1。

    

 1 void bitOperate()
 2 {//对所有子集遍历,每次求出一个子集
 3     for(int i = 0; i < (1 << n); i++)
 4     {
 5         for(int j = 0; j < n; j++)
 6         {//对第i个子集进行筛选
 7             if( (i & (1 << j) ) == 0)
 8                 x[j] = 0;
 9             else
10                 x[j] = 1;
11         }
12         for(int j = 0; j < n; j++)
13             cout<<x[j];
14         cout<<endl;
15     }
16 }

    有很多朋友可能刚刚看到的这段代码回犯迷糊,其实这个为什么要叫位运算法呢?个人认为可能是用了位操作得名的吧。其实它的核心并非是利用了位运算而得到一个遍历的方法,位运算只是起到一个计算工具的作用,其核心还是利用"位"当了一个标志,

怎么说呢。一个大小为n的集合,其子集为2^n个(不懂的回去看看高中课本),正好我们可以利用二进制数来表示每一个子集(给它们起名字),集合与集合之间不同体现在元素,当元素为数字时,可以更加细化:集合之间不同在于元素的数量和元素的值。这两个正好对应二进制中1的位置。比如一个集合用8即(1000),这就表示第0号元素存在,其他元素不存在的集合。

    了解了这些,就可以在内层中用下标j来进行循环求出下标为j的元素是否存在于这个子集中。保存存在的元素,那么就得到了这个子集了。

     以上为大家介绍了了leetcode Subsets题目的核心算法,当然只是数学方法,具体编程的实现大家可以自己去试试!

时间: 2024-10-10 02:39:31

Subsets的相关文章

Subsets &lt;leetcode&gt;

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

[LeetCode] Backtracking Template for (Subsets, Permutations, and Combination Sum)

根据issac3 用Java总结了backtracking template, 我用他的方法改成了Python. 以下为template. 1 def backtrack(ans, temp, nums, start): # 可能有start, 也可能没有 2 if len(temp) == len(nums): 3 ans.append(temp) 4 else: 5 for i in range(start, len(nums)): 6 if nums[i] not in temp: 7 b

Solution to LeetCode Problem Set

Here is my collection of solutions to leetcode problems. LeetCode - Course Schedule LeetCode - Reverse Linked List LeetCode - Isomorphic Strings LeetCode - Count Primes LeetCode - Remove Linked List Elements LeetCode - Happy Number LeetCode - Bitwise

LeetCode OJ - Subsets 1 &amp;&amp; 2

这道题的做法,一定得掌握啊!!!  elegant & beautiful & concise 下面是AC代码: 1 /** 2 * Given a set of distinct integers, S, return all possible subsets. 3 * 这道题的做法应该要记住!!!!! 4 * @param s 5 * @return 6 */ 7 public ArrayList<ArrayList<Integer>> subsets(int[

LeetCode Subsets (DFS)

题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. 1 class Solution { 2 public: 3 vector<vector<int>> subsets(vector<int>& nums) { 4 sort(nums.begin(),nums.end()); 5 DFS(0,nums,tmp); 6 return a

LeetCode --- 90. Subsets II

题目链接:Subsets 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]

[LeetCode] Subsets [31]

题目 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]

leetcode: Subsets &amp; Subsets II

SubsetsGiven 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

LeetCode Subsets II (DFS)

题意: 给一个集合,有n个可能相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: 看这个就差不多了.LEETCODE SUBSETS (DFS) 1 class Solution { 2 public: 3 vector<vector<int>> subsets(vector<int>& nums) { 4 sort(nums.begin(),nums.end()); 5 DFS(0,nums,tmp); 6 ans.push_back(vector

[leetcode]Subsets II @ Python

原题地址:https://oj.leetcode.com/problems/subsets-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 duplicat