[LintCode] Subsets

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

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

Example

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

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

Challenge

Can you do it in both recursively and iteratively?

Solution 1. Recursion

 1 class Solution {
 2     public ArrayList<ArrayList<Integer>> subsets(int[] nums) {
 3         ArrayList<ArrayList<Integer>> results = new ArrayList<ArrayList<Integer>>();
 4         if(nums == null){
 5             return results;
 6         }
 7         Arrays.sort(nums);
 8         getSubsets(results, new ArrayList<Integer>(), nums, 0);
 9         return results;
10     }
11
12     private void getSubsets(ArrayList<ArrayList<Integer>> results,
13                             ArrayList<Integer> result,
14                             int[] nums, int startIdx){
15         results.add(new ArrayList<Integer>(result));
16         for(int i = startIdx; i < nums.length; i++){
17             result.add(nums[i]);
18             getSubsets(results, result, nums, i + 1);
19             result.remove(result.size() - 1);
20         }
21     }
22 }

Solution 2. Iterative

Algorithm:

if there are n elements in nums[], then we‘ll have 2^n different subsets in total.

Each outer loop genereates a different subset. For a given i, its bits of 1 represent

that which elements should be included in the ith subset.

Each inner loop checks if nums[j] should be included in the ith subset.

For example, nums = {1, 2, 3}, i = 5 with binary representation of 101. This means

nums[0] and nums[2] should be included in the 5th subset.

Then in the inner loop checks if each nums[j] should be included in the 5th subset.

 1 class Solution {
 2     public ArrayList<ArrayList<Integer>> subsets(int[] nums) {
 3         ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
 4         int n = nums.length;
 5         Arrays.sort(nums);
 6
 7         for (int i = 0; i < (1 << n); i++) {
 8             ArrayList<Integer> subset = new ArrayList<Integer>();
 9             for (int j = 0; j < n; j++) {
10                 // check whether the jth digit in i‘s binary representation is 1
11                 if ((i & (1 << j)) != 0) {
12                     subset.add(nums[j]);
13                 }
14             }
15             result.add(subset);
16         }
17
18         return result;
19     }
20 }

Both solutions‘ runtime are O(2^n), and it is already optimal since there are 2^n different subsets to generate.

Related Problems

Subsets II

Restore IP Address

时间: 2024-11-05 18:38:28

[LintCode] Subsets的相关文章

lintcode 中等题:subsets II 带重复元素的子集

题目 带重复元素的子集 给定一个可能具有重复数字的列表,返回其所有可能的子集 样例 如果 S = [1,2,2],一个可能的答案为: [ [2], [1], [1,2,2], [2,2], [1,2], [] ] 注意 子集中的每个元素都是非降序的 两个子集间的顺序是无关紧要的 解集中不能包含重复子集 挑战 你可以同时用递归与非递归的方式解决么? 解题 一个很简单的想法就是在上一题目中增加判断是否已经存在某个子集 class Solution: """ @param S: A

【Lintcode】017.Subsets

题目: 题解: Solution 1 () class Solution { public: vector<vector<int> > subsets(vector<int> &S) { vector<vector<int> > res{{}}; sort(S.begin(), S.end()); for (int i = 0; i < S.size(); ++i) { int size = res.size(); for (int

Lintcode17 Subsets solution 题解

[题目描述] Given a set of distinct integers, return all possible subsets. Notice:Elements in a subset must be in non-descending order;The solution set must not contain duplicate subsets. 给定一个含不同整数的集合,返回其所有的子集 注意:子集中的元素排列必须是非降序的,解集必须不包含重复的子集 [题目链接] http:/

Lintcode18 Subsets II solution 题解

[题目描述] Given a list of numbers that may has duplicate numbers, return all possible subsets Notice:Each element in a subset must be in non-descending order.The ordering between two subsets is free.The solution set must not contain duplicate subsets. 给

由LintCode问题子集出发,浅析ArrayList的拷贝问题

在做LintCode上的递归类题目子集时,我一开始的想法是递归到最后一层即单元素时然后开始逐层返回,产生相应的每层的子集并添加到最终的结果中去.于是乎有了以下代码: public List<List<Integer>> findSolution(int[] nums, int begin, int end){ List<List<Integer>> result = new ArrayList<>(); List<List<Integ

lintcode:子集 &amp; 带重复元素的子集

地址: http://lintcode.com/zh-cn/problem/subsets/ http://lintcode.com/zh-cn/problem/subsets-ii/ 子集 其实就是一颗子集树 class Solution { public: vector<vector<int>> res; vector<int> judge; int len; /* * @param nums: A set of numbers * @return: A list

[lintcode the-smallest-difference]最小差(python)

题目链接:http://www.lintcode.com/zh-cn/problem/the-smallest-difference/ 给定两个整数数组(第一个是数组 A,第二个是数组 B),在数组 A 中取 A[i],数组 B 中取 B[j],A[i] 和 B[j]两者的差越小越好(|A[i] - B[j]|).返回最小差. 排好序后用两个指针分别扫描两个数组,每次更新他们的差值的绝对值.并且依据他们两个数字的大小来决定谁来移动指针. 1 class Solution: 2 # @param

Subsets II [leetcode] 从获取子集的递归和循环方法说起,解决重复子集的问题

这一题和Permutation II很像,一个是排列一个是组合. 我们理清思路,从最基本的获取子集的方法开始分析: 获取子集总的来说可以用循环或者递归做,同时还可以根据数字对应的binary code得到. 例如s = {x,y,z}可以生成的组合有:x,y,z,xy,yz,xz,xyz,0 第一种思路: 1. 维护一个集合Set(i),包含s[0...i]可生成的所有组合 s[0...i+1]可以生成的所有组合为:Set(i) + (Set(i)+s[i+1]) void permutatio

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[