高效的程序,用于打印/返回数组中大小为3的所有增加的子序列

时间:2011-02-01 19:23:22

标签: algorithm

给出类似

的数组

1,6,5,2,3,4

我们需要打印

1 2 3
1 3 4
1 2 4
2 3 4

最好的方法是什么? 这是动态编程吗?

有没有比暴力O(n3)更好的方法?我确信有。

我说动态编程的原因是因为我可以将其视为

  • 表示“1”(使用大小为2的子序列打印数组其余部分的子问题的所有结果)。

  • 表示'2'(打印所有数组其余部分子问题的结果,大小为2的子句)

继续这样。

然而,上述两个结果有很多重叠,所以我们需要找到一种有效的重用方式,我想。

嗯,这些只是随意的想法。你可以用正确的appraoch纠正我。

好的,让我纠正,如果不打印,我需要返回不同的增加序列。我的观点是,我需要找到一种方法,以最有效的方式获得这些序列。

3 个答案:

答案 0 :(得分:2)

您可以浏览数组并记住在当前点之前可能的部分序列。打印并忘记任何长度为3的序列。

示例:

(1 6 5 2 3 4)
  ^
remember ((1))

(1 6 5 2 3 4)
    ^
remember ((1) (1 6) (6))

(1 6 5 2 3 4)
      ^
remember ((1) (1 6) (6) (1 5) (5))

(1 6 5 2 3 4)
        ^
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2))

(1 6 5 2 3 4)
          ^
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2) (1 3) (1 2 3) (2 3) (3))
print and forget (1 2 3)
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2) (1 3) (2 3) (3))

(1 6 5 2 3 4)
            ^
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2) (1 3) (2 3) (3) (1 4) (1 2 4) (2 4)
          (1 3 4) (2 3 4) (3 4) (4))
print and forget (1 2 4)
print and forget (1 3 4)
print and forget (2 3 4)
done.

挑战似乎在于为记忆的子序列选择合适的数据结构。

答案 1 :(得分:2)

在一般情况下,你必须根据两件事来计算复杂性:

1- Count of input numbers (I will call it b)
2- Length of output (I will call it d)

我能想到的一个通用方法是在O(n ^ 2)中构造一个类似的问题图: enter image description here

如果较小的数字后面有一个较大的数字,则从较小的数字到它有一个有向边。

现在为了找到长度为d的所有序列,您需要从每个数字开始并输出所有长度路径(d-1)。

如果使用像BFS这样的遍历方法,复杂度将小于O(d x(b ^(d - 1)))。

但是,您可以使用相邻矩阵乘法来查找长度为d的路径,这将使复杂度降低到小于O((d - 2)x(b ^ 3))。 (邻接矩阵的第N个幂将告诉你每个节点到另一个节点有多少条路径,长度为N)。

algorithms来减少方矩阵乘法复杂度。

答案 2 :(得分:0)

  1. 创建有序对(a,b)的列表,使得< b和Index(a)<指数(B)。为O(n ^ 2)
  2. 在O(n ^ 2log(n))中对此列表进行排序(在a或b上 - 无关紧要)。可以根据数据结构制作O(nlog(n))。
  3. 对于列表中的每个元素,使用二分查找找到所有匹配的有序对 - 最差情况为O(n ^ 3log(n)),平均情况为O(n ^ 2log(n))