Algorithm 计算两个整数序列间Kendall-Tau距离的快速算法

Algorithm 计算两个整数序列间Kendall-Tau距离的快速算法,algorithm,Algorithm,我得到两个长度相等的整数序列,例如 3 1 2 5 4 532114 我想找出两个序列之间的Kendall-Tau距离,也就是序列之间的反向对数。例如,我们在第一个序列中有(3,5)(3在5之前),在第二个序列中有(5,3)。我做了一个快速的O(n^2)算法来检查这个数字,但是对于长度为40000或更大的序列来说,它的计算量太大了。我读过,我可以在做冒泡排序时计算倒数,将第一个序列转换成第二个序列,但这又是O(n^2) 无符号短n,第一个[50001],第二个[50001],s; 整数和=0;

我得到两个长度相等的整数序列,例如

3 1 2 5 4

532114

我想找出两个序列之间的Kendall-Tau距离,也就是序列之间的反向对数。例如,我们在第一个序列中有(3,5)(3在5之前),在第二个序列中有(5,3)。我做了一个快速的O(n^2)算法来检查这个数字,但是对于长度为40000或更大的序列来说,它的计算量太大了。我读过,我可以在做冒泡排序时计算倒数,将第一个序列转换成第二个序列,但这又是O(n^2)

无符号短n,第一个[50001],第二个[50001],s;
整数和=0;
cin>>n;
对于(int i=1;i>first[i];
}
//在第二个数组中,将序列中的实际条目与其索引交换
//这样我们就可以快速检查一对是否颠倒
对于(int i=1;i>s
第二[s]=i;
}
对于(int i=1;i=second[first[j]])sum++;
}

这个问题似乎与数组中的反转计数问题密切相关,不同之处在于,在这种情况下,反转意味着“元素相对于其他序列交换”,而不是“元素无序”。因为存在一个很好的O(n log n)-计算反演的时间算法,似乎有理由尝试找到一种方法来调整该算法以解决这个特殊问题

用于计数反转的分治算法基于mergesort,并假设给定序列中的任意两个元素,有一种快速(O(1)-时间)的方法来比较它们,看看它们是否在正确的顺序中。如果我们能找到一种方法,以某种方式注释第二个序列的元素,以便在时间O(1)中我们可以确定序列中的任何一对元素是有序的还是无序的,然后我们可以运行快速计数反转算法来得到你想要的答案


这里有一种方法可以做到这一点。创建一些辅助数据结构(例如,平衡的BST),将第一个数组的元素与其在第一个数组中的索引相关联。然后,复制第二个数组,将每个元素及其在第一个数组中的对应位置注释。这总共需要时间O(n log n)。然后,运行标准的O(n logn)-时间算法来计算第二个数组中的反转数,除了在比较元素时,通过它们的关联索引而不是它们的值进行比较。这总共需要时间O(n logn)完成。

这就解决了问题,多亏了一点,因为您似乎在关注代码而不是算法,所以我将这个问题迁移到堆栈溢出。
  unsigned short n, first[50001], second[50001], s;
  int sum = 0;
  cin >> n;
  for(int i=1; i<n+1; i++){
        cin >> first[i];
  }
  // in the second array exchange the actual entries in the sequence with their indices
  // that way we can quickly check if a pair is inverted
  for(int i=1; i<n+1; i++){
        cin >> s
        second[s]=i;
  }
  for(int i=1; i<n+1; i++){
      for (int j = i+1; j < n+1; j++)
        // i < j always
        // when we check the indices of the respective entries in the second array
        // the relationship should stay otherwise we have an inversion
        if(second[first[i]]>=second[first[j]])sum++;
  }