据我所知,这个问题可以通过利用选择和分区,这两者都可以在线性时间内完成最有效地得到解决。我的想法是选择数组O(n)中的第n个最小元素,在这个例子中给出的将是34,所以在这种情况下为j = 3
。然后from i = 1 to j - 1
,如果序列递减,则设置B[i] = j
,序列增加的那一刻,设置B[i] = i + 1
并停止。递归调用数组A[j ... n]
上的过程。我不认为这是有效的,也不确定它是否正确,或者算法的最终复杂程度如何。
摘要
(1)选择第n个最小(索引j)利用确定性选择算法O(N)
(2)
function:
for i = 1 to n do
for j = i + 1 to n do
if A[j] > A[i] then B[i] = j , B[j] = n + 1
for k = i + 1 to j - 1 do
if A[k] < A[k + 1]
B[k] = j
else
B[k] = k + 1
recursive function(A[j + 1, ... n]) // recursively perform procedure on portion of array starting from j + 1 (after max) to n.
也许你可以使用合并排序(O(nlogn)),你可以将两个数组分成n个子列表,每个列表包含1个元素。然后重复合并子列表以获得新的已排序的子列表,直到只剩下1个子列表。 –
@VictorLuna我认为这是一个正确的解决方案,但不是最有效的。我相信这个问题可以在O(n) –
中完成。实际上合并排序它不是O(nlogn),它是O(n + m)。因为列表就像队列一样,所以它们指向要在每个数组中使用的下一个元素。在插入它们之前比较这些值时,确切地说有n + m个比较,使其在运行时为O(n)。 –