Java 求数组笛卡尔积的时间复杂度
我想知道我的解决方案的时间复杂度,以及是否有任何方法可以改进解决方案。这是Java 求数组笛卡尔积的时间复杂度,java,performance,time-complexity,cartesian-product,Java,Performance,Time Complexity,Cartesian Product,我想知道我的解决方案的时间复杂度,以及是否有任何方法可以改进解决方案。这是O(| first |*|*|*|*| third |*…)而你无法在这个界限上改进θ,而不仅仅是O 结果本身就非常大(在您的示例中,27=3*3*3),您需要创建每个结果,这样您就不会得到比结果大小更好的结果。从而得出Omega界 O部分非常简单,因为代码执行的所有子操作都在Theta(1)中。所以我们只需要考虑回路。最内部的循环生成结果,每个结果打印一次。因此,您的算法是最优的,每个正确的结果迭代一次。您不会生成需要丢
O(| first |*|*|*|*| third |*…)
而你无法在这个界限上改进θ
,而不仅仅是O
结果本身就非常大(在您的示例中,27=3*3*3),您需要创建每个结果,这样您就不会得到比结果大小更好的结果。从而得出Omega
界
O
部分非常简单,因为代码执行的所有子操作都在Theta(1)
中。所以我们只需要考虑回路。最内部的循环生成结果,每个结果打印一次。因此,您的算法是最优的,每个正确的结果迭代一次。您不会生成需要丢弃的无用对,也不会在它们之间使用任何非常量操作。由于仅结果的数量就达到了上述的复杂性,因此您的代码也太复杂了
对于精确的边界,我们需要包括每个子元素的大小,如前所示。但是如果您想要一个大小变量,比如说
n
,您可以通过最大数组的大小绑定其他大小:
a d f
b d f
c d f
a e f
b e f
c e f
a i f
b i f
c i f
a d g
b d g
c d g
a e g
b e g
c e g
a i g
b i g
c i g
a d h
b d h
c d h
a e h
b e h
c e h
a i h
b i h
c i h
然后你得到
n = max(|first|, |second|, |third|, ...)
其中
x
是传入的数组数量。因此,在您的示例中,它将是Theta(n^3)
我认识的许多人都认为将combinations*=set[I].length
移动到循环体中,而不是将其移动到循环头中是更好的方式。@ReazMurshed对于n的任何合理定义,复杂性肯定不是O(n^2)。这是指数型的。我知道已经一年多了,但是你可能想看看Guava的实现:我理解你答案的逻辑,这是正确的,但是对比这个解决方案和我的另一个解决方案:Guava脚本的执行时间几乎是恒定的,不管数组的长度我看这里没有冲突。Big-O分析不涉及实际的实时性,任何因素都被完全忽略。例如,只有在输入了不切实际的数据之后,情况才会变得更糟。Big-O一点也不关心这一点。我知道执行时间是不同的,因为复杂性符号是在操作数中定义的,但这就是为什么我对guava的实现发表了评论。我仍然在尝试,因为我对java不是很有经验,但是由于我使用它们的函数时运行时间是恒定的,因此操作的数量似乎不会随着每个输入数组的长度而变化,只有外部数组的总数。它看起来是恒定的,因为它们的实现对于您测试的所有输入都非常快。而且,他们的列表是不可变的,所以他们实际上不会创建新的真正的列表,而只会创建迷你包装器,从而再次加快了速度。我想得到一个深入的答案,我建议您提出一个新问题,包括使用基准框架的实现和基准测试。试一试大列表,大约100个列表,每个都有100k条目的条目,现在你会看到一个性能冲击。
n = max(|first|, |second|, |third|, ...)
Theta(n^x)