📜  计算前 N 个自然数排列中的反转

📅  最后修改于: 2021-09-03 13:46:43             🧑  作者: Mango

给定一个数组,大小为N的数组arr[]表示从1N的数字排列,任务是计算数组中的反转次数。
注意:如果a[i] > a[j]i < j,则两个数组元素a[i]a[j]形成反转

例子:

以下文章讨论了解决反转计数的不同方法:

  • 朴素和修改后的归并排序
  • 使用 AVL 树
  • 使用比特

方法:这个问题可以通过使用二分查找来解决。请按照以下步骤解决问题:

  • 将范围[1, N]中的数字按升序存储在向量V 中
  • 初始化一个变量ans0以存储数组arr[] 中的反转次数。
  • 使用变量i在范围[0, N-1] 中迭代
    • arr[i]的出现索引存储在向量V 中 在变量索引中
    • 添加位置小于向量中存在的索引的数字的计数, V,因为它们小于当前元素并因此形成反转。
    • 从向量V 中移除位置index处的元素。
  • 打印ans的值作为结果。

下面是上述方法的实现:

C++14
// C++ program for the above approach
#include 
using namespace std;
 
// Function to count number of inversions in
// a permutation of first N natural numbers
int countInversions(int arr[], int n)
{
    vector v;
 
    // Store array elements in sorted order
    for (int i = 1; i <= n; i++) {
        v.push_back(i);
    }
 
    // Store the count of inversions
    int ans = 0;
 
    // Traverse the array
    for (int i = 0; i < n; i++) {
 
        // Store the index of first
        // occurrence of arr[i] in vector V
        auto itr = lower_bound(
            v.begin(), v.end(), arr[i]);
 
        // Add count of smaller elements
        // than current element
        ans += itr - v.begin();
 
        // Erase current element from
        // vector and go to next index
        v.erase(itr);
    }
 
    // Print the result
    cout << ans;
 
    return 0;
}
 
// Driver Code
int main()
{
 
    // Given Input
    int arr[] = { 2, 3, 1, 5, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    countInversions(arr, n);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.Vector;
 
class GFG{
 
// Function to count number of inversions in
// a permutation of first N natural numbers
static void countInversions(int arr[], int n)
{
    Vector v = new Vector<>();
 
    // Store array elements in sorted order
    for(int i = 1; i <= n; i++)
    {
        v.add(i);
    }
 
    // Store the count of inversions
    int ans = 0;
 
    // Traverse the array
    for(int i = 0; i < n; i++)
    {
         
        // Store the index of first
        // occurrence of arr[i] in vector V
        int itr = v.indexOf(arr[i]);
 
        // Add count of smaller elements
        // than current element
        ans += itr;
 
        // Erase current element from
        // vector and go to next index
        v.remove(itr);
    }
 
    // Print the result
    System.out.println(ans);
}
 
// Driver code
public static void main(String[] args)
{
     
    // Given Input
    int arr[] = { 2, 3, 1, 5, 4 };
    int n = arr.length;
 
    // Function Call
    countInversions(arr, n);
}
}
 
// This code is contributed by abhinavjain194


输出:
3

时间复杂度: O(N*log(N))
辅助空间: O(N)