给定一个数组,大小为N的数组arr[]表示从1到N的数字排列,任务是计算数组中的反转次数。
注意:如果a[i] > a[j]且i < j,则两个数组元素a[i]和a[j]形成反转。
例子:
Input: arr[] = {2, 3, 1, 5, 4}
Output: 3
Explanation: Given array has 3 inversions: (2, 1), (3, 1), (5, 4).
Input: arr[] = {3, 1, 2}
Output: 2
Explanation: Given array has 2 inversions: (3, 1), (3, 2).
以下文章讨论了解决反转计数的不同方法:
- 朴素和修改后的归并排序
- 使用 AVL 树
- 使用比特
方法:这个问题可以通过使用二分查找来解决。请按照以下步骤解决问题:
- 将范围[1, N]中的数字按升序存储在向量V 中。
- 初始化一个变量ans为0以存储数组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)