【问题标题】:Is there an algorithm to count array inversions in linear time?是否有一种算法可以在线性时间内计算数组反转?
【发布时间】:2014-06-02 17:17:24
【问题描述】:

我知道 n 元素数组中inversions 的数量可以用 O(n log(n) ) 操作使用enhanced merge sort

但是,我遇到了一个不同的解决方案,只要输入是 (1, 2, 3, ..., n-1, n):

编辑:-


我很抱歉我粘贴的代码在所有情况下都不起作用。实际上,这段代码用于this question,并且通过了所有案例。但我仍然留下代码,以便它可以作为一些直觉,也许会出现这个问题的线性时间解决方案。

注意:- 下面提到的代码不正确。


/* int in = 0;
    for (int i = 0; i < n; i++) {
        a[i] = a[i] - i - 1;
    }
    for (int i = 0; i < n; i++) {
        if (a[i] > 0)
            in = in + a[i];
        else if (a[i] < -1)
            in = in - a[i] - 1;
    } */ 

现在的问题是我们能否为这个问题提出一个线性时间解决方案?

【问题讨论】:

  • 该代码是否正确复制? i 在内部和外部 for 循环中被修改?
  • 在这种情况下到底什么是反转?
  • 当 a[i] > a[j] 并且 i
  • @Spundum 这是通过合并排序计算反转的链接geeksforgeeks.org/counting-inversions
  • @Spundum 归并排序方法是一种通用算法,适用于任何类型的数组,但上述算法仅适用于数组是 1,2,3 的随机排列... N。例如,如果 N =4 。那么数组可以是2,4,3,1。

标签: c arrays algorithm


【解决方案1】:

显而易见的答案是它没有。例如,对于 n = 4a = {2, 3, 4, 1},您的代码给出了答案 5,即使正确的反转计数显然是 3。

【讨论】:

    【解决方案2】:

    方法是错误的! 考虑下面的例子!

    int a[] = { 2, 3, 1 };
    
    int in = 0;
    
    for (int i = 0; i < n; i++) {
        a[i] = a[i] - i - 1;
    }
    
    // a[] = { 1, 1, -2 };
    
    for (int i = 0; i < n; i++) {
        if (a[i] > 0)
            in = in + a[i];
        else if (a[i] < -1)
            in = in - a[i] - 1;
    } 
    
    // in = 1 + 1 - (-1) = 3
    

    正确答案是 2,但这里返回 3!

    【讨论】:

      猜你喜欢
      • 2019-05-20
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 2013-02-03
      • 2019-07-23
      • 2010-11-17
      • 2014-07-20
      • 2020-02-24
      相关资源
      最近更新 更多