排列中的升序子序列

时间:2011-05-01 10:24:25

标签: c++ algorithm

给定置换1 ... n例如5 3 4 1 2 如何在线性时间内找到长度为3的所有上升子序列?

是否有可能找到长度为X的其他升序子序列? X

我不知道如何在线性时间内解决它。

2 个答案:

答案 0 :(得分:2)

你需要实际的提升序列吗?或者只是升序子序列的数量?

无法在少于列出它们所需的时间内生成它们。正如已经指出的那样,O(NX / (X-1)!)。 (X可能存在意外因素,因为列出大小为O(X)的数据结构需要时间X。)对它们进行明显的递归搜索并不远。

如果使用动态编程,可以及时计算它们O(X * N2)。这是Python的。

counts = []
answer = 0
for i in range(len(perm)):
    inner_counts = [0 for k in range(X)]
    inner_counts[0] = 1
    for j in range(i):
        if perm[j] < perm[i]:
            for k in range(1, X):
                inner_counts[k] += counts[j][k-1]
    counts.add(inner_counts)
    answer += inner_counts[-1]

对于您的示例3 5 1 2 4 6X = 3,您将结束:

counts = [
    [1, 0, 0],
    [1, 1, 0],
    [1, 0, 0],
    [1, 1, 0],
    [1, 3, 1],
    [1, 5, 5]
]
answer = 6

(上面只找到5个,缺少的是2 4 6。)

扩展这个答案并不难创建一个数据结构,可以很容易地直接列出它们,找到一个随机数据等。

答案 1 :(得分:1)

您无法在线性时间内找到所有升序子序列,因为可能会有更多的后续序列。

例如,在排序的原始序列中,所有子集都在增加子序列,因此长度为N(1,2,...,N)的排序序列具有N选择k = n!/(n-k)!k!增加长度为k的子序列