的功率集 {1, 2, 3}
是: {{}, {2}, {3}, {2, 3}, {1, 2}, {1, 3}, {1, 2, 3}, {1}}
假设我有一个 Set
在java中:
Set<Integer> mySet = new HashSet<Integer>();
mySet.add(1);
mySet.add(2);
mySet.add(3);
Set<Set<Integer>> powerSet = getPowerset(mySet);
如何以最佳的复杂度顺序编写getpowerset函数(我想可能是o(2^n)
26条答案
按热度按时间aor9mmx11#
没有递归的一种方法是:使用二进制掩码并进行所有可能的组合。
xbp102n02#
我在寻找一个解决方案,它不像这里贴的那么大。这是针对Java7的,因此对于版本5和版本6,它将需要少量的粘贴。
下面是一些要测试的示例代码:
xyhw6mcr3#
是的,是的
O(2^n)
事实上,既然你需要生成,2^n
可能的组合。下面是一个工作实现,使用泛型和集合:还有一个测试,给出你的示例输入:
wa7juj8i4#
这是我对兰博达斯的态度。
或并行(请参见parallel()注解):
输入集大小:18
逻辑处理器:8à 3.4兆赫
性能提升:30%
bmvo0sr55#
这里有一个解决方案,我使用一个发电机,优点是,整个发电机组从来没有存储在一次。。。所以你可以一个接一个地迭代它,而不需要把它存储在内存中。我想这是个更好的选择。。。注意复杂性是相同的,o(2^n),但是内存需求减少了(假设垃圾收集器的行为是!;)
要调用它,请使用以下模式:
它来自我的项目库…:)
sczxawaw6#
下面是一个教程,详细描述了您想要的内容,包括代码。你是对的,复杂性是o(2^n)。
piwo6bdm7#
t的子集是通过去掉t的零个或多个元素而形成的任何集合。withoutfirst子集将t中缺少第一个元素的子集相加,for循环将处理将子集与第一个元素相加的问题。例如,如果t包含元素[“1”、“2”、“3”],missingfirst将添加[[“”]、[“2”]、[“3”]、[“2”、“3”]],for循环将在这些元素前面粘贴“1”,并将其添加到newset。因此,我们将以[[“”],[“1”],[“2”],[“3”],[“1”,“2”],[“1”,“3”],[“2”,“3”],[“1”,“2”,“3”]。
kninwzqo8#
如果您使用的是eclipse集合(以前称为gs集合),那么可以使用
powerSet()
所有可设置项上的方法。注意:我是eclipse集合的提交者。
cclgggtu9#
如果n<63,这是一个合理的假设,因为无论如何都要尝试构造幂集时内存不足(除非使用迭代器实现),这是一种更简洁的方法。二进制运算比
Math.pow()
和数组的掩码,但不知何故java用户害怕他们。。。q7solyqu10#
实际上,我已经编写了一些代码来满足您在o(1)中的要求。问题是你下一步打算怎么处理这台电视机。如果你要打电话
size()
在它上面,这是o(1),但是如果你要迭代它,那显然是O(2^n)
.contains()
会是O(n)
等等。你真的需要这个吗?
编辑:
这段代码现在在guava中可用,并通过该方法公开
Sets.powerSet(set)
.3qpi33ja11#
我最近不得不使用这样的东西,但是首先需要最小的子列表(有1个元素,然后是2个元素,…)。我不想把空的也不想把整张单子都包括进去。而且,我不需要返回所有子列表的列表,我只需要对每个子列表做一些处理。
希望不使用递归实现这一点,并提出了以下建议(将“正在做的事情”抽象为一个函数接口):
这样,也很容易将其限制为特定长度的子列表。
zte4gxcn12#
当集合的大小很大时,上面的一些解决方案会受到影响,因为它们会创建大量要收集的对象垃圾,并且需要复制数据。我们怎样才能避免呢?我们可以利用这样一个事实,即我们知道结果集的大小将有多大(2^n),预先分配一个那么大的数组,然后只附加到它的末尾,从不复制。
加速比随n的增加而迅速增大。我把它比作乔ão席尔瓦的解决方案。在我的机器上(所有测量值都是近似值),n=13快5倍,n=14快7倍,n=15快12倍,n=16快25倍,n=17快75倍,n=18快140倍。因此,垃圾创建/收集和复制在其他类似的big-o解决方案中占主导地位。
与让数组动态增长相比,在开始时预分配数组似乎是一种胜利。当n=18时,动态增长所需的时间大约是整体增长的两倍。
nfg76nw013#
算法:
输入:设置[],设置大小1。获取幂集powet\ U set\ U size=pow(2,set\ U size)2循环的大小,计数器从0到pow\ U set\ U size(a)循环i=0到set\ U size(i),如果计数器中的第i位被设置,则打印该子集集合中的第i个元素(b)打印子集合的分隔符,即换行符
44u64gxh14#
下面是一个简单的迭代o(2^n)解:
oymdgrw715#