第五期:实现一个算法求某集合的所有子集(二进制法)
此博客根据哔哩哔哩中蓝桥杯相关视频,仅用于自己学习,如有侵犯版权,立马删除。
题目分析:以集合a={A,B,C}为例
所谓子集,就是在原集合中选取若干个(不大于原集合的个数)元素即可,对于每一个元素有两种状态,要么选,要么不选,可以巧妙的借助 二进制 。
进一步分析:
000–>ABC都不选,那么集合为{ }
001–>AB不选,C选,那么集合为{C}
010–>AC不选,B选,那么集合为{B}
011–>A不选,BC选,那么集合为{B,C}
100–>A选,BC不选,那么集合为{A}
101–>AB不选,C选,那么集合为{A,C}
110–>AB选,C不选,那么集合为{A,B}
111–>ABC都选,那么集合为{A,B,C}
Java代码:
import java.util.ArrayList;
import java.util.Arrays;
/**
* 求一个集合的子集
*/
public class SubSet2 {
private static ArrayList<ArrayList<Integer>> getSubsets(int[] arr, int len){
Arrays.sort(arr);
// 大集合,存放最后的结果
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
for (int i = (int)Math.pow(2,len)-1; i >= 0; i--) {
ArrayList<Integer> temp = new ArrayList<>();
for (int j = len-1; j >= 0 ; j--) { // 检查哪个位置上的元素是一
if (((i>>j)&1)==1){
temp.add(arr[j]);
}
}
result.add(temp);
}
return result;
}
public static void main(String[] args) {
int[] array = {1, 4, 6};
ArrayList<ArrayList<Integer>> subsets = getSubsets(array, array.length);
System.out.println(subsets);
}
}
简要分析:
时间复杂度: O ( 2 n ) O({2^n}) O(2n)