遍历整数数组所有组合的算法

Posted

技术标签:

【中文标题】遍历整数数组所有组合的算法【英文标题】:Algorithm to run through all combinations of integer array 【发布时间】:2016-02-11 20:05:25 【问题描述】:

遍历整数数组的所有不同排列的最有效算法是什么?具体来说,我有一个数组,它可以在 C++ 术语中保存 4 个大小为 uint32_t 的元素,但我需要在 Java 中实现它,所以我想我需要使用 long 将它限制在 4,294,967,295。所以一个示例输出将是这样的:

[1,1,1,1]
[2,1,1,1]
[3,1,1,1]
[4,1,1,1]
[1,2,1,1]
[1,3,1,1]
[1,4,1,1]
[1,1,2,1]
[1,1,3,1]
[1,1,4,1]
...
[4,294,967,295, 4,294,967,295, 4,294,967,295, 4,294,967,295]

它不需要按那个顺序进行。只要它尝试所有组合。

谢谢!

【问题讨论】:

这些既不是排列也不是组合,至少在技术意义上是这样。 另外,那将是10^38 不同的可能性。 这很可能是一个 XY 问题...您要解决的真正问题是什么?因为仅使用int 需要很长时间,我什至无法想象使用long 需要多长时间... 你为什么要打印它,你没有做任何算法盟友,从 1 到 4,294,967,295 的任何 4 个随机数都是你的排列之一。 【参考方案1】:

希望您耐心等待,因为有很多可能的组合。

您不允许 0,因此总数略少于 2128 个可能的组合。其中只有 4,294,967,2954,即 340,282,366,604,025,813,516,997,721,482,669,850,625。

因此,如果您每秒可以处理一亿个这样的数据,那么只需要 10,790,283,060,756,779,982,147 年的时间来计算、给予或取消一个宇宙的生命周期。

您可能需要一个更好的策略来找到正确的解决方案,而不是蛮力枚举所有可能性。

【讨论】:

【参考方案2】:

只需几个循环:

for (int a = 0; a != max_int; ++a) 
    for (int b = 0; b != max_int; ++b) 
        for (int c = 0; c != max_int; ++c) 
            for (int d = 0; d != max_int; ++d) 
                std::cout << a << b << c << d << std::endl;
            
        
    

【讨论】:

有太多的可能,这永远不会结束。请注意,OP 也希望处理 long,而不仅仅是 int... @Tunaki,我要解决的问题是这些组合之一是正确答案,但我不知道是哪个。不幸的是,我只选择 long,因为 Java 中没有 uint 的概念 :( 这正是我所担心的。而且,好吧,你做错了!你根本无法产生所有的可能性……太多了。您要解决的问题必须从不同的角度解决;蛮力不是唯一的解决方案。 如果您不知道价值是什么,您将如何解决?

以上是关于遍历整数数组所有组合的算法的主要内容,如果未能解决你的问题,请参考以下文章

不定长数组取值交叉遍历组合生成算法

Hot10039. 组合总和

LeetCode回溯算法#01图解组合问题

[电商]商品发布规格组合算法

[算法]数组中未出现的最小正整数

两数之和