【发布时间】:2014-08-12 21:30:15
【问题描述】:
n 的排列是一个长度为n 的数组A,每个包含条目1,2,...,n。
置换A 的逆下降集是一个0-1 数组D,长度为n-1,其中D[i] = 0 如果i+1 在A 中i+2 的左侧,否则@ 987654333@。
示例 (n=4):
[1, 2, 3, 4] [0, 0, 0]
[1, 2, 4, 3] [0, 0, 1]
[1, 3, 4, 2] [0, 1, 0]
[2, 3, 4, 1] [1, 0, 0]
[1, 3, 2, 4] [0, 1, 0]
[2, 3, 1, 4] [1, 0, 0]
[1, 4, 2, 3] [0, 0, 1]
[1, 4, 3, 2] [0, 1, 1]
[2, 4, 3, 1] [1, 0, 1]
[3, 4, 2, 1] [1, 1, 0]
[2, 1, 3, 4] [1, 0, 0]
[3, 1, 2, 4] [0, 1, 0]
[4, 1, 2, 3] [0, 0, 1]
[2, 1, 4, 3] [1, 0, 1]
[3, 1, 4, 2] [0, 1, 0]
[2, 4, 1, 3] [1, 0, 1]
[3, 4, 1, 2] [0, 1, 0]
[3, 2, 1, 4] [1, 1, 0]
[4, 2, 1, 3] [1, 0, 1]
[4, 3, 1, 2] [0, 1, 1]
[3, 2, 4, 1] [1, 1, 0]
[4, 2, 3, 1] [1, 0, 1]
[4, 1, 3, 2] [0, 1, 1]
[4, 3, 2, 1] [1, 1, 1]
计算排列的逆下降集的简单方法是O(n^2)。我真的想要更快的东西。这是天真的事情
for (int i=0; i<n-1; ++i) {
for (int j=i+1; j<n; ++j) {
if (A[j] == i+2) {
D[i] = 1;
break;
} else if (A[j] = i+1) {
D[i] = 0;
break;
}
}
}
这被称为逆下降,因为如果你取排列的逆然后取通常的下降集,你就会得到它。排列A 的通常下降集是一个长度为n-1 的数组D,其中D[i] = 1 如果A[i] > A[i+1] 和0 否则。
因此,一种想法是计算置换的逆,然后在一次通过O(n) 中获取下降集。然而,我知道的最好的取反方法仍然是O(n^2),所以这并不能节省任何东西,但也许有更快的方法。
我正在用 C++ 编写,但任何伪代码解决方案都会很棒。
【问题讨论】:
标签: c++ algorithm permutation