数组的反转计数指示–数组要排序的距离(或距离)。如果已对数组进行排序,则反转计数为0。如果以相反顺序对数组进行排序,则反转计数为最大。
Two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j.
For simplicity, we may assume that all elements are unique.
因此,我们的任务是计算数组中的反转次数。那是这样的一对元素(a [i],a [j])的数量:
- a [i]> a [j]并且
- 我
范例:
Input: arr[] = {8, 4, 2, 1}
Output: 6
Given array has six inversions (8, 4), (4, 2),
(8, 2), (8, 1), (4, 1), (2, 1).
Input: arr[] = { 1, 20, 6, 4, 5 }
Output: 5
- 天真的和修改的合并排序
- 使用AVL树
- 使用BIT
方法:
我们将在数组中向后迭代,并将每个元素存储到Trie中。要在Trie中存储号码,我们
必须将数字分解为二进制形式,如果该位为0,则表示我们将该位存储到当前节点的左指针中;如果为1 ,则将其存储到当前节点的右指针中,并相应地进行更改当前节点。我们还将维护该计数,该计数表示直到该节点为止,有多少个数字遵循相同的路径。
特里节点的结构
struct node{
int count;
node* left;
node* right;
};
在任何时候,当我们存储这些位时,我们碰巧移至右指针(即位为1),我们将检查左子级是否存在,这意味着存在小于当前数字的数字。被存储到Trie中时,这些数字仅是反转计数,因此我们会将其添加到计数中。
下面是实施方法
C++
// C++ implementation
#include
using namespace std;
// Structure of the node
struct Node {
int count;
Node* left;
Node* right;
};
// function to initialize
// new node
Node* makeNewNode()
{
Node* temp = new Node;
temp->count = 1;
temp->left = NULL;
temp->right = NULL;
return temp;
}
// Insert element in trie
void insertElement(int num,
Node* root,
int& ans)
{
// Converting the number
// into binary form
for (int i = 63; i >= 0; i--) {
// Checking if the i-th
// bit ios set or not
int a = (num & (1 << i));
// If the bit is 1
if (a != 0) {
// if the bit is 1 that means
// we have to go to the right
// but we also checks if left
// pointer exists i.e there is
// at least a number smaller than
// the current number already in
// the trie we add that count
// to ans
if (root->left != NULL)
ans += root->left->count;
// If right pointer is not NULL
// we just iterate to that
// position and increment the count
if (root->right != NULL) {
root = root->right;
root->count += 1;
}
// If right is NULL we add a new
// node over there and initialize
// the count with 1
else {
Node* temp = makeNewNode();
root->right = temp;
root = root->right;
}
}
// if the bit is 0
else {
// We have to iterate to left,
// we first check if left
// exists? if yes then change
// the root and the count
if (root->left != NULL) {
root = root->left;
root->count++;
}
// otherwise we create
// the left node
else {
Node* temp = makeNewNode();
root->left = temp;
root = root->left;
}
}
}
}
// function to count
// the inversions
int getInvCount(int arr[], int n)
{
Node* head = makeNewNode();
int ans = 0;
for (int i = n - 1; i >= 0; i--) {
// inserting each element in Trie
insertElement(arr[i],
head,
ans);
}
return ans;
}
// Driver Code
int main()
{
int arr[] = { 8, 4, 2, 1 };
int n = sizeof(arr) / sizeof(int);
cout << "Number of inversions are : "
<< getInvCount(arr, n);
return 0;
}
Java
// Java implementation of above idea
import java.util.*;
class GFG
{
// Structure of the node
static class Node
{
int count;
Node left;
Node right;
};
static int ans;
// function to initialize
// new node
static Node makeNewNode()
{
Node temp = new Node();
temp.count = 1;
temp.left = null;
temp.right = null;
return temp;
}
// Insert element in trie
static void insertElement(int num,
Node root)
{
// Converting the number
// into binary form
for (int i = 63; i >= 0; i--)
{
// Checking if the i-th
// bit ios set or not
int a = (num & (1 << i));
// If the bit is 1
if (a != 0)
{
// if the bit is 1 that means
// we have to go to the right
// but we also checks if left
// pointer exists i.e there is
// at least a number smaller than
// the current number already in
// the trie we add that count
// to ans
if (root.left != null)
ans += root.left.count;
// If right pointer is not null
// we just iterate to that
// position and increment the count
if (root.right != null)
{
root = root.right;
root.count += 1;
}
// If right is null we add a new
// node over there and initialize
// the count with 1
else
{
Node temp = makeNewNode();
root.right = temp;
root = root.right;
}
}
// if the bit is 0
else
{
// We have to iterate to left,
// we first check if left
// exists? if yes then change
// the root and the count
if (root.left != null)
{
root = root.left;
root.count++;
}
// otherwise we create
// the left node
else
{
Node temp = makeNewNode();
root.left = temp;
root = root.left;
}
}
}
}
// function to count
// the inversions
static int getInvCount(int arr[], int n)
{
Node head = makeNewNode();
ans = 0;
for (int i = n - 1; i >= 0; i--)
{
// inserting each element in Trie
insertElement(arr[i],
head);
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 8, 4, 2, 1 };
int n = arr.length;
System.out.print("Number of inversions are : "
+ getInvCount(arr, n));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation
# Structure of the node
class Node:
def __init__(self):
self.left = self.right = None
self.count = 1
# function to initialize
# new node
def makeNewNode():
temp = Node()
return temp
# Insert element in trie
def insertElement(num, root, ans):
# Converting the number
# into binary form
for i in range(63, -1, -1):
# Checking if the i-th
# bit ios set or not
a = (num & (1 << i));
# If the bit is 1
if (a != 0):
# if the bit is 1 that means
# we have to go to the right
# but we also checks if left
# pointer exists i.e there is
# at least a number smaller than
# the current number already in
# the trie we add that count
# to ans
if (root.left != None):
ans += root.left.count;
# If right pointer is not None
# we just iterate to that
# position and increment the count
if (root.right != None):
root = root.right;
root.count += 1;
# If right is None we add a new
# node over there and initialize
# the count with 1
else:
temp = makeNewNode();
root.right = temp;
root = root.right;
# if the bit is 0
else:
# We have to iterate to left,
# we first check if left
# exists? if yes then change
# the root and the count
if (root.left != None):
root = root.left;
root.count += 1
# otherwise we create
# the left node
else:
temp = makeNewNode();
root.left = temp;
root = root.left;
return ans
# function to count
# the inversions
def getInvCount(arr, n):
head = makeNewNode();
ans = 0;
for i in range(n - 1 ,-1, -1):
# inserting each element in Trie
ans = insertElement(arr[i], head, ans);
return ans;
# Driver Code
if __name__=='__main__':
arr = [ 8, 4, 2, 1 ]
n = len(arr)
print("Number of inversions are : " + str(getInvCount(arr, n)))
# This code is contributed by rutvik_56
C#
// C# implementation of above idea
using System;
class GFG
{
// Structure of the node
public class Node
{
public int count;
public Node left;
public Node right;
};
static int ans;
// function to initialize
// new node
static Node makeNewNode()
{
Node temp = new Node();
temp.count = 1;
temp.left = null;
temp.right = null;
return temp;
}
// Insert element in trie
static void insertElement(int num,
Node root)
{
// Converting the number
// into binary form
for (int i = 63; i >= 0; i--)
{
// Checking if the i-th
// bit ios set or not
int a = (num & (1 << i));
// If the bit is 1
if (a != 0)
{
// if the bit is 1 that means
// we have to go to the right
// but we also checks if left
// pointer exists i.e there is
// at least a number smaller than
// the current number already in
// the trie we add that count
// to ans
if (root.left != null)
ans += root.left.count;
// If right pointer is not null
// we just iterate to that
// position and increment the count
if (root.right != null)
{
root = root.right;
root.count += 1;
}
// If right is null we add a new
// node over there and initialize
// the count with 1
else
{
Node temp = makeNewNode();
root.right = temp;
root = root.right;
}
}
// if the bit is 0
else
{
// We have to iterate to left,
// we first check if left
// exists? if yes then change
// the root and the count
if (root.left != null)
{
root = root.left;
root.count++;
}
// otherwise we create
// the left node
else
{
Node temp = makeNewNode();
root.left = temp;
root = root.left;
}
}
}
}
// function to count the inversions
static int getInvCount(int []arr, int n)
{
Node head = makeNewNode();
ans = 0;
for (int i = n - 1; i >= 0; i--)
{
// inserting each element in Trie
insertElement(arr[i], head);
}
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 8, 4, 2, 1 };
int n = arr.Length;
Console.Write("Number of inversions are : " +
getInvCount(arr, n));
}
}
// This code is contributed by 29AjayKumar
输出:
Number of inversions are : 6
时间复杂度:
辅助空间: