Efficient program to print/return all increasing subsequences of size 3 in an array
给定一个像
这样的数组
1、6、5、2、3、4
我们需要打印
1 2 3 4 | 1 2 3 1 3 4 1 2 4 2 3 4 |
最好的方法是什么?
这是动态规划吗?
有没有比蛮力 O(n3) 更好的方法?我确定有。
我说动态编程的原因是因为我可以将其视为类似
-
for \\'1\\'(打印数组其余部分子问题的所有结果,子序列大小为 2)。
-
for \\'2\\'(打印数组其余部分子问题的所有结果,子序列大小为 2)
然后这样继续。
但是,以上两个结果有很多重叠之处,所以我想我们需要找到一种有效的方法来重用它。
嗯,这些只是随机的想法。你可以用正确的方法纠正我。
好的,让我纠正一下,如果不打印,我需要返回不同的递增序列。我的意思是,我需要找到一种方法以最有效的方式处理这些序列。
在一般情况下,您必须根据两件事来计算复杂度:
1 2 | 1- Count of input numbers (I will call it b) 2- Length of output (I will call it d) |
我能想到的一个广义的方法,就是在O(n^2)中构造一个与问题类似的图:
如果一个较大的数字出现在一个较小的数字之后,则从较小的数字到它有一条有向边。
现在为了找到所有长度为 d 的序列,您需要从每个数字开始并输出所有长度为 (d - 1) 的路径。
如果你使用像 BFS 这样的遍历方法,复杂度将小于 O(d x (b ^ (d - 1)))。
但是,您可以使用相邻矩阵乘法来找到长度为 d 的路径,这会将复杂度降低到小于 O((d - 2) x (b ^ 3)) 的程度。 (邻接矩阵的 N 次方将告诉您从每个节点到另一个节点存在多少条长度为 N 的路径。
有一些算法可以稍微降低方阵乘法的复杂度。
您可以遍历数组并记住在当前点之前可能出现的部分序列。打印并忘记任何长度达到 3.
的序列
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | (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. |
挑战似乎在于为记住的子序列选择合适的数据结构。