给定N
- 长度数组B
,找到[1 .. N]
,A
的排列,以便B[i]
是{A
中的元素数量1}}对于大于A[i]
的所有索引,大于i
。
示例:N = 4, B=[1 1 1 0]
输出:A=[3 2 1 4]
有人可以帮我解决这个问题的算法吗?
进一步说明:B[i]
在索引A[i]
之后的数组A[]
中的项数大于i
。即对于大于i
的所有指数。例如:B[2]=1
表示在A[]
中的第3个元素之后,有一个元素大于A[2]
。
提前致谢
答案 0 :(得分:3)
这似乎有效:从临时列表T := [ N, N-1, N-2, ..., 3, 2, 1 ]
开始。此列表的编号范围为0
到N-1
,类似于C#中的List<int>
。
选择T[B[0]]
。那是你在结果数组中的第0个成员,所以设置A[0] := T[B[0]]
。 从T
删除此号码。列表T
现在减少了一个元素。现在已将其编入0
到N-2
。
然后设置A[1] := T[B[1]]
,并从T
中删除该号码。依此类推,A[i] := T[B[i]]
,其中T
在任何时间只包含直到那时“未使用”的数字。
在伪代码中:
set T := [ N, N-1, N-2, ..., 3, 2, 1 ]
for (i from 0 through N-1)
A[i] := T[B[i]]
T.RemoveAtIndex(B[i])
问题B=[1 1 1 0]
中的示例如下:
T = [ 4, 3, 2, 1 ], A = [ ]
在索引1
处阅读和删除:
T = [ 4, 2, 1 ], A = [ 3 ]
在索引1
处阅读和删除:
T = [ 4, 1 ], A = [ 3, 2 ]
在索引1
处阅读和删除:
T = [ 4 ], A = [ 3, 2, 1 ]
在索引0
处阅读和删除:
T = [ ], A = [ 3, 2, 1, 4 ]
编辑:我发现这称为Lehmer codes。
答案 1 :(得分:0)
我想到的答案之一是下面的算法:
For i = N to 1
A[i] = N - B[i]
For j = i+1 to N
If A[j] <= A[i]
A[j]--