计算数组中的反转 - 特殊情况

时间:2016-05-14 17:22:56

标签: algorithm data-structures

数组的反转计数表示 - 数组的排序距离(或接近)。如果数组已经排序,则反转计数为0.如果数组按相反顺序排序,则反转计数最大。 从形式上讲,如果a [i]> 1,则[i]和[j]两个元素形成反转。 a [j]和i< j示例: 序列2,4,1,3,5有三个反转(2,1),(4,1),(4,3)。

现在,有各种算法可以在O(n log n)中解决这个问题。

有一种特殊情况,数组只有3种类型的元素--1,2和3.现在,是否可以计算O(n)中的反转?

例如1,1,3,2,3,1,3

2 个答案:

答案 0 :(得分:4)

是的。只需取3个整数a,b,c,其中a是1到1的遇到的数量,b是迄今为止遇到的2个数,c是到目前为止遇到的3个人数。鉴于此,遵循下面的算法(我假设数字在数组arr中给出,大小为n,基于1的索引,也只是一个伪代码)

    no_of_inv = 0
    a = 0
    b = 0
    c = 0
    for i from 1 to n:
       if arr[i] == 1:
          no_of_inv = no_of_inv + b + c 
          a++
       else if arr[i] == 2:
          no_of_inv = no_of_inv + c
          b++
       else:
          c++

答案 1 :(得分:1)

(这个算法与Sasha非常相似。我只是想提供一个解释。)

每次反转(i, j)都满足0 ≤ i < j < n。我们将S[j]定义为(i, j)形式的反转次数;也就是说,S[j]A[i] > A[j]的{​​{1}}次。然后,反转的总数为0 ≤ i < j

T = S[0] + S[1] + … + S[n - 1]C[x][j]的{​​{1}}次。所有A[i] > x然后0 ≤ i < j。如果我们可以在线性时间内计算S[j] = C[A[j]][j]j,那么我们可以在线性时间内计算3n

这是一些Python代码:

C[x][j]

通过不同时存储所有S值,可以提高效率 - 尽管不是在asmpytotic术语中。该算法实际上只需要通过数组一次。我选择以这种方式呈现它,因为它最简洁。

相关问题