LeetCode Online Judge 题目C# 练习 - Subsets
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,3],
[2,3],
[1,2],
[]
]
1 public static List<List<int>> Subsets2(List<int> S) 2 { 3 S.Sort(); 4 List<List<int>> ret = new List<List<int>>(); 5 6 List<int> empty = new List<int>(); 7 ret.Add(empty); 8 9 for (int i = 0; i < S.Count; i++) 10 { 11 int prev_count = ret.Count; 12 for (int j = 0; j < prev_count; j++) 13 { 14 List<int> temp = new List<int>(ret[j]); 15 temp.Add(S[i]); 16 ret.Add(temp); 17 } 18 } 19 20 return ret; 21 }
代码分析:
DP,第一次做居然想不到,看来复习很重要。 用一个prev_count记录上一次DP的时候做到哪里,不然ret.Count 在里往里 Add 的时候会不停增加的。
1 public static List<List<int>> Subsets(List<int> S) 2 { 3 List<List<int>> ret = new List<List<int>>(); 4 SubsetsRecursive(ret, S, 0); 5 return ret; 6 } 7 8 public static void SubsetsRecursive(List<List<int>> ret, List<int> S, int index) 9 { 10 if (index == S.Count) 11 ret.Add(new List<int>()); 12 else 13 { 14 SubsetsRecursive(ret, S, index + 1); 15 int n = ret.Count; 16 for (int i = 0; i < n; i++) 17 { 18 List<int> temp = new List<int>(ret[i]); 19 temp.Add(S[index]); 20 ret.Add(temp); 21 } 22 } 23 }
代码分析:
这就是之前想的递归方法,没多大区别。而且还不符合题目 non-descending 的要求。因为递归是从最后一个element开始加的。如果要用这个方法,就要把输入数组 S,descendly sort一次,这里要用到delegate 做 comparsion. 我就懒得做了。
1 public static List<List<int>> SubsetsCombinatoric(List<int> S) 2 { 3 S.Sort(); 4 List<List<int>> ret = new List<List<int>>(); 5 6 for (int i = 0; i < (1 << S.Count); i++) 7 { 8 int k = i; 9 int index = 0; 10 List<int> subset = new List<int>(); 11 while (k > 0) 12 { 13 if ((k & 1) > 0) 14 { 15 subset.Add(S[index]); 16 } 17 k >>= 1; 18 index++; 19 } 20 ret.Add(subset); 21 } 22 23 return ret; 24 }
代码分析:
介绍一种比较不一样的方法——Combinatoric。
例子: S = { 1, 2, 3}
i = 0 : (1 << S.Count - 1) = 0 : 111 (就是S有3个数,i 最大到 111, 4个数, i 最大就到 1111 。。。)
然后 k = i; k & 1 == 1 就把相应 S[index] 加到答案里面。然后k >>= 1;
k = 0;(0x0) {}
k = 1;(0x1) {1}
k = 2;(0x10) {2},
k = 3;(0x11) {1,2};
k = 4;(0x100) {3};
k = 5;(0x101) {1,3};
k = 6;(0x110) {2,3};
k = 7;(0x111) {1,2,3};