给定N个整数的数组arr [] 。任务是找到反转数。如果arr [i]> arr [j]且i
例子
Input: arr[] = {8, 4, 2, 1}
Output: 6
Explanation:
Given array has six inversions:
- (8, 4): arr[0] > arr[1] and 0 < 1
- (8, 2): arr[0] > arr[2] and 0 < 2
- (8, 1): arr[0] > arr[3] and 0 < 3
- (4, 2): arr[1] > arr[2] and 1 < 2
- (4, 1): arr[1] > arr[3] and 1 < 3
- (2, 1): arr[2] > arr[3] and 2 < 3
Input: arr[] = {2, 3}
Output: 0
Explanation:
There is no such pair exists such that arr[i] > arr[j] and i < j.
我们已经讨论了以下方法:
- 计算数组中的反转设置1(使用合并排序)
- 计算数组中的反转|设置2(使用自平衡BST)
- 使用C++ STL中的Set计数反转
- 计算数组中的反转|第3组(使用BIT)
在本文中,我们将讨论一种使用有序集和GNU C++ PBDS的方法。
方法:
我们将使用函数order_of_key(K) ,该函数在对数N时间返回严格小于K的元素数。
- 将数组的第一个元素插入Ordered_Set中。
- 对于arr []中的所有其余元素,请执行以下操作:
- 将当前元素插入Ordered_Set中。
- 使用函数order_of_key(arr [i] +1)在Ordered_Set中找到严格小于当前元素+ 1的元素数。
- Ordered_Set和order_of_key(current_element + 1)大小之间的差异将给出当前元素的反转计数。
例如:
arr[] = {8, 4, 2, 1} Ordered_Set S = {8} For remaining element in arr[]: At index 1, the element is 4 S = {4, 8} key = order_of_key(5) = 1 The difference between size of S and key gives the total number of inversion count for that current element. inversion_count = S.size() - key = 2 - 1 = 1 Inversion Pairs are: (8, 4) At index 2, the element is 2 S = {2, 4, 8} key = order_of_key(3) = 1 inversion_count = S.size() - key = 3 - 1 = 2 Inversion Pairs are: (8, 2) and (4, 2) At index 3, the element is 1 S = {1, 2, 4, 8} key = order_of_key(2) = 1 inversion_count = S.size() - key = 4 - 1 = 3 Inversion Pairs are: (8, 1), (4, 1) and (2, 1) Total inversion count = 1 + 2 + 3 = 6
下面是上述方法的实现:
// Ordered set in GNU C++ based
// approach for inversion count
#include
#include
#include
using namespace __gnu_pbds;
using namespace std;
// Ordered Set Tree
typedef tree,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
// Returns inversion count in
// arr[0..n-1]
int getInvCount(int arr[], int n)
{
int key;
// Intialise the ordered_set
ordered_set set1;
// Insert the first
// element in set
set1.insert(arr[0]);
// Intialise inversion
// count to zero
int invcount = 0;
// Finding the inversion
// count for current element
for (int i = 1; i < n; i++) {
set1.insert(arr[i]);
// Number of elements strictly
// less than arr[i]+1
key = set1.order_of_key(arr[i] + 1);
// Difference between set size
// and key will give the
// inversion count
invcount += set1.size() - key;
}
return invcount;
}
// Driver's Code
int main()
{
int arr[] = { 8, 4, 2, 1 };
int n = sizeof(arr) / sizeof(int);
// Function call to count
// inversion
cout << getInvCount(arr, n);
return 0;
}
输出:
6
时间复杂度: O(Nlog N)