[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

原文地址:https://www.cnblogs.com/lz87/p/7304844.html