El conteo de inversión para una array indica qué tan lejos (o cerca) está la array de ser ordenada. Si la array ya está ordenada, el recuento de inversión es 0. Si la array está ordenada en orden inverso, el recuento de inversión es el máximo.
Dos elementos a[i] y a[j] forman una inversión si a[i] > a[j] e i < j. Para simplificar, podemos suponer que todos los elementos son únicos.
Ejemplo:
Entrada: arr[] = {8, 4, 2, 1}
Salida: 6
Explicación: La array dada tiene seis inversiones: (8,4), (4,2), (8,2), (8,1), (4,1), (2,1).Entrada: arr[] = {3, 1, 2}
Salida: 2
Explicación: La array dada tiene dos inversiones: (3,1), (3,2).
Le recomendamos encarecidamente que haga clic aquí y lo practique antes de pasar a la solución.
Ya hemos discutido los siguientes métodos para resolver el conteo de inversión:
Le recomendamos que consulte el Árbol indexado binario (BIT) antes de seguir leyendo esta publicación.
Solución usando BIT de tamaño Θ(maxElement):
- Enfoque: recorra la array y, para cada índice, encuentre la cantidad de elementos más pequeños en el lado derecho de la array. Esto se puede hacer usando BIT. Sume los recuentos de todos los índices de la array e imprima la suma.
- Antecedentes sobre el TBI:
- BIT básicamente admite dos operaciones para una array arr[] de tamaño n:
- Suma de elementos hasta arr[i] en tiempo O(log n).
- Actualice un elemento de array en tiempo O (log n).
- BIT se implementa mediante una array y funciona en forma de árboles. Tenga en cuenta que hay dos formas de ver BIT como un árbol.
- La operación de suma donde el padre del índice x es “x – (x & -x)”.
- La operación de actualización donde el padre del índice x es «x + (x & -x)».
- BIT básicamente admite dos operaciones para una array arr[] de tamaño n:
- Algoritmo:
- Cree un BIT, para encontrar el conteo de los elementos más pequeños en el BIT para un número dado y también un resultado variable = 0 .
- Atraviesa la array de un extremo a otro.
- Para cada índice, verifique cuántos números menos que el elemento actual están presentes en BIT y agréguelos al resultado
- Para obtener el recuento de elementos más pequeños, se utiliza getSum() de BIT .
- En su idea básica, BIT se representa como una array de tamaño igual al elemento máximo más uno. Para que los elementos se puedan usar como un índice.
- Después de eso, agregamos el elemento actual al BIT[] realizando una operación de actualización que actualiza el conteo del elemento actual de 0 a 1 y, por lo tanto, actualiza los ancestros del elemento actual en BIT (consulte update() en BIT para obtener más detalles) .
A continuación se muestra la implementación del enfoque anterior:
C++
// C++ program to count inversions using Binary Indexed Tree #include<bits/stdc++.h> using namespace std; // Returns sum of arr[0..index]. This function assumes // that the array is preprocessed and partial sums of // array elements are stored in BITree[]. int getSum(int BITree[], int index) { int sum = 0; // Initialize result // Traverse ancestors of BITree[index] while (index > 0) { // Add current element of BITree to sum sum += BITree[index]; // Move index to parent node in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index Tree (BITree) at given index // in BITree. The given value 'val' is added to BITree[i] and // all of its ancestors in tree. void updateBIT(int BITree[], int n, int index, int val) { // Traverse all ancestors and add 'val' while (index <= n) { // Add 'val' to current node of BI Tree BITree[index] += val; // Update index to that of parent in update View index += index & (-index); } } // Returns inversion count arr[0..n-1] int getInvCount(int arr[], int n) { int invcount = 0; // Initialize result // Find maximum element in arr[] int maxElement = 0; for (int i=0; i<n; i++) if (maxElement < arr[i]) maxElement = arr[i]; // Create a BIT with size equal to maxElement+1 (Extra // one is used so that elements can be directly be // used as index) int BIT[maxElement+1]; for (int i=1; i<=maxElement; i++) BIT[i] = 0; // Traverse all elements from right. for (int i=n-1; i>=0; i--) { // Get count of elements smaller than arr[i] invcount += getSum(BIT, arr[i]-1); // Add current element to BIT updateBIT(BIT, maxElement, arr[i], 1); } return invcount; } // Driver program 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 program to count inversions // using Binary Indexed Tree class GFG { // Returns sum of arr[0..index]. // This function assumes that the // array is preprocessed and partial // sums of array elements are stored // in BITree[]. static int getSum(int[] BITree, int index) { int sum = 0; // Initialize result // Traverse ancestors of BITree[index] while (index > 0) { // Add current element of BITree to sum sum += BITree[index]; // Move index to parent node in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index // Tree (BITree) at given index // in BITree. The given value 'val' // is added to BITree[i] and all // of its ancestors in tree. static void updateBIT(int[] BITree, int n, int index, int val) { // Traverse all ancestors and add 'val' while (index <= n) { // Add 'val' to current node of BI Tree BITree[index] += val; // Update index to that of parent in update View index += index & (-index); } } // Returns inversion count arr[0..n-1] static int getInvCount(int[] arr, int n) { int invcount = 0; // Initialize result // Find maximum element in arr[] int maxElement = 0; for (int i = 0; i < n; i++) if (maxElement < arr[i]) maxElement = arr[i]; // Create a BIT with size equal to // maxElement+1 (Extra one is used so // that elements can be directly be // used as index) int[] BIT = new int[maxElement + 1]; for (int i = 1; i <= maxElement; i++) BIT[i] = 0; // Traverse all elements from right. for (int i = n - 1; i >= 0; i--) { // Get count of elements smaller than arr[i] invcount += getSum(BIT, arr[i] - 1); // Add current element to BIT updateBIT(BIT, maxElement, arr[i], 1); } return invcount; } // Driver code public static void main (String[] args) { int []arr = {8, 4, 2, 1}; int n = arr.length; System.out.println("Number of inversions are : " + getInvCount(arr,n)); } } // This code is contributed by mits
Python3
# Python3 program to count inversions using # Binary Indexed Tree # Returns sum of arr[0..index]. This function # assumes that the array is preprocessed and # partial sums of array elements are stored # in BITree[]. def getSum( BITree, index): sum = 0 # Initialize result # Traverse ancestors of BITree[index] while (index > 0): # Add current element of BITree to sum sum += BITree[index] # Move index to parent node in getSum View index -= index & (-index) return sum # Updates a node in Binary Index Tree (BITree) # at given index in BITree. The given value # 'val' is added to BITree[i] and all of its # ancestors in tree. def updateBIT(BITree, n, index, val): # Traverse all ancestors and add 'val' while (index <= n): # Add 'val' to current node of BI Tree BITree[index] += val # Update index to that of parent # in update View index += index & (-index) # Returns count of inversions of size three def getInvCount(arr, n): invcount = 0 # Initialize result # Find maximum element in arrays maxElement = max(arr) # Create a BIT with size equal to # maxElement+1 (Extra one is used # so that elements can be directly # be used as index) BIT = [0] * (maxElement + 1) for i in range(n - 1, -1, -1): invcount += getSum(BIT, arr[i] - 1) updateBIT(BIT, maxElement, arr[i], 1) return invcount # Driver code if __name__ =="__main__": arr = [8, 4, 2, 1] n = 4 print("Inversion Count : ", getInvCount(arr, n)) # This code is contributed by # Shubham Singh(SHUBHAMSINGH10)
C#
// C# program to count inversions // using Binary Indexed Tree using System; class GFG { // Returns sum of arr[0..index]. // This function assumes that the // array is preprocessed and partial // sums of array elements are stored // in BITree[]. static int getSum(int []BITree, int index) { int sum = 0; // Initialize result // Traverse ancestors of BITree[index] while (index > 0) { // Add current element of BITree to sum sum += BITree[index]; // Move index to parent node in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index // Tree (BITree) at given index // in BITree. The given value 'val' // is added to BITree[i] and all // of its ancestors in tree. static void updateBIT(int []BITree, int n, int index, int val) { // Traverse all ancestors and add 'val' while (index <= n) { // Add 'val' to current node of BI Tree BITree[index] += val; // Update index to that of parent in update View index += index & (-index); } } // Returns inversion count arr[0..n-1] static int getInvCount(int []arr, int n) { int invcount = 0; // Initialize result // Find maximum element in arr[] int maxElement = 0; for (int i = 0; i < n; i++) if (maxElement < arr[i]) maxElement = arr[i]; // Create a BIT with size equal to // maxElement+1 (Extra one is used so // that elements can be directly be // used as index) int[] BIT = new int[maxElement + 1]; for (int i = 1; i <= maxElement; i++) BIT[i] = 0; // Traverse all elements from right. for (int i = n - 1; i >= 0; i--) { // Get count of elements smaller than arr[i] invcount += getSum(BIT, arr[i] - 1); // Add current element to BIT updateBIT(BIT, maxElement, arr[i], 1); } return invcount; } // Driver code static void Main() { int []arr = {8, 4, 2, 1}; int n = arr.Length; Console.WriteLine("Number of inversions are : " + getInvCount(arr,n)); } } // This code is contributed by mits
PHP
<?php // PHP program to count inversions // using Binary Indexed Tree // Returns sum of arr[0..index]. // This function assumes that the // array is preprocessed and partial // sums of array elements are stored // in BITree[]. function getSum($BITree, $index) { $sum = 0; // Initialize result // Traverse ancestors of BITree[index] while ($index > 0) { // Add current element of BITree to sum $sum += $BITree[$index]; // Move index to parent node in getSum View $index -= $index & (-$index); } return $sum; } // Updates a node in Binary Index // Tree (BITree) at given index // in BITree. The given value 'val' // is added to BITree[i] and // all of its ancestors in tree. function updateBIT(&$BITree, $n, $index,$val) { // Traverse all ancestors and add 'val' while ($index <= $n) { // Add 'val' to current node of BI Tree $BITree[$index] += $val; // Update index to that of // parent in update View $index += $index & (-$index); } } // Returns inversion count arr[0..n-1] function getInvCount($arr, $n) { $invcount = 0; // Initialize result // Find maximum element in arr[] $maxElement = 0; for ($i=0; $i<$n; $i++) if ($maxElement < $arr[$i]) $maxElement = $arr[$i]; // Create a BIT with size equal // to maxElement+1 (Extra one is // used so that elements can be // directly be used as index) $BIT=array_fill(0,$maxElement+1,0); // Traverse all elements from right. for ($i=$n-1; $i>=0; $i--) { // Get count of elements smaller than arr[i] $invcount += getSum($BIT, $arr[$i]-1); // Add current element to BIT updateBIT($BIT, $maxElement, $arr[$i], 1); } return $invcount; } // Driver program $arr = array(8, 4, 2, 1); $n = count($arr); print("Number of inversions are : ".getInvCount($arr,$n)); // This code is contributed by mits ?>
Javascript
<script> // javascript program to count inversions // using Binary Indexed Tree // Returns sum of arr[0..index]. // This function assumes that the // array is preprocessed and partial // sums of array elements are stored // in BITree. function getSum(BITree , index) { var sum = 0; // Initialize result // Traverse ancestors of BITree[index] while (index > 0) { // Add current element of BITree to sum sum += BITree[index]; // Move index to parent node in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index // Tree (BITree) at given index // in BITree. The given value 'val' // is added to BITree[i] and all // of its ancestors in tree. function updateBIT(BITree , n, index , val) { // Traverse all ancestors and add 'val' while (index <= n) { // Add 'val' to current node of BI Tree BITree[index] += val; // Update index to that of parent in update View index += index & (-index); } } // Returns inversion count arr[0..n-1] function getInvCount(arr , n) { var invcount = 0; // Initialize result // Find maximum element in arr var maxElement = 0; for (i = 0; i < n; i++) if (maxElement < arr[i]) maxElement = arr[i]; // Create a BIT with size equal to // maxElement+1 (Extra one is used so // that elements can be directly be // used as index) var BIT = Array.from({length: maxElement + 1}, (_, i) => 0); for (i = 1; i <= maxElement; i++) BIT[i] = 0; // Traverse all elements from right. for (i = n - 1; i >= 0; i--) { // Get count of elements smaller than arr[i] invcount += getSum(BIT, arr[i] - 1); // Add current element to BIT updateBIT(BIT, maxElement, arr[i], 1); } return invcount; } // Driver code var arr = [8, 4, 2, 1]; var n = arr.length; document.write("Number of inversions are : " + getInvCount(arr,n)); // This code is contributed by Amit Katiyar </script>
Number of inversions are : 6
Complejidad de tiempo: – La función de actualización y la función getSum se ejecutan para O (log (elemento máximo)). La función getSum debe ejecutarse para cada elemento de la array. Entonces, la complejidad del tiempo general es: O (nlog (elemento máximo)).
Espacio auxiliar: O(maxElement), el espacio requerido para el BIT es una array del tamaño del elemento más grande.
Mejor solución usando BIT de tamaño Θ(n):
Enfoque: Atraviese la array y para cada índice encuentre la cantidad de elementos más pequeños en su lado derecho de la array. Esto se puede hacer usando BIT. Sume los recuentos de todos los índices de la array e imprima la suma. El enfoque sigue siendo el mismo, pero el problema con el enfoque anterior es que no funciona para números negativos, ya que el índice no puede ser negativo. La idea es convertir la array dada en una array con valores de 1 a n y el orden relativo de los elementos más pequeños y más grandes sigue siendo el mismo.
Ejemplo :
arr[] = {7, -90, 100, 1} It gets converted to, arr[] = {3, 1, 4 ,2 } as -90 < 1 < 7 < 100. Explanation: Make a BIT array of a number of elements instead of a maximum element. Changing element will not have any change in the answer as the greater elements remain greater and at the same position.
Algoritmo:
- Cree un BIT, para encontrar el conteo de los elementos más pequeños en el BIT para un número dado y también un resultado variable = 0 .
- La solución anterior no funciona para arrays que contienen elementos negativos. Entonces, convierta la array en una array que contenga una numeración relativa de elementos, es decir, haga una copia de la array original y luego ordene la copia de la array y reemplace los elementos de la array original con los índices de los mismos elementos en la array ordenada.
Por ejemplo, si la array es {-3, 2, 0}, la array se convierte en {1, 3, 2} - Atraviesa la array de un extremo a otro.
- Para cada índice, verifique cuántos números menos que el elemento actual están presentes en BIT y agréguelos al resultado
A continuación se muestra la implementación del enfoque anterior:
C++
// C++ program to count inversions using Binary Indexed Tree #include<bits/stdc++.h> using namespace std; // Returns sum of arr[0..index]. This function assumes // that the array is preprocessed and partial sums of // array elements are stored in BITree[]. int getSum(int BITree[], int index) { int sum = 0; // Initialize result // Traverse ancestors of BITree[index] while (index > 0) { // Add current element of BITree to sum sum += BITree[index]; // Move index to parent node in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index Tree (BITree) at given index // in BITree. The given value 'val' is added to BITree[i] and // all of its ancestors in tree. void updateBIT(int BITree[], int n, int index, int val) { // Traverse all ancestors and add 'val' while (index <= n) { // Add 'val' to current node of BI Tree BITree[index] += val; // Update index to that of parent in update View index += index & (-index); } } // Converts an array to an array with values from 1 to n // and relative order of smaller and greater elements remains // same. For example, {7, -90, 100, 1} is converted to // {3, 1, 4 ,2 } void convert(int arr[], int n) { // Create a copy of arrp[] in temp and sort the temp array // in increasing order int temp[n]; for (int i=0; i<n; i++) temp[i] = arr[i]; sort(temp, temp+n); // Traverse all array elements for (int i=0; i<n; i++) { // lower_bound() Returns pointer to the first element // greater than or equal to arr[i] arr[i] = lower_bound(temp, temp+n, arr[i]) - temp + 1; } } // Returns inversion count arr[0..n-1] int getInvCount(int arr[], int n) { int invcount = 0; // Initialize result // Convert arr[] to an array with values from 1 to n and // relative order of smaller and greater elements remains // same. For example, {7, -90, 100, 1} is converted to // {3, 1, 4 ,2 } convert(arr, n); // Create a BIT with size equal to maxElement+1 (Extra // one is used so that elements can be directly be // used as index) int BIT[n+1]; for (int i=1; i<=n; i++) BIT[i] = 0; // Traverse all elements from right. for (int i=n-1; i>=0; i--) { // Get count of elements smaller than arr[i] invcount += getSum(BIT, arr[i]-1); // Add current element to BIT updateBIT(BIT, n, arr[i], 1); } return invcount; } // Driver program 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 program to count inversions // using Binary Indexed Tree import java.util.*; class GFG{ // Returns sum of arr[0..index]. // This function assumes that the // array is preprocessed and partial // sums of array elements are stored // in BITree[]. static int getSum(int BITree[], int index) { // Initialize result int sum = 0; // Traverse ancestors of // BITree[index] while (index > 0) { // Add current element of // BITree to sum sum += BITree[index]; // Move index to parent node // in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index Tree // (BITree) at given index in BITree. // The given value 'val' is added to // BITree[i] and all of its ancestors // in tree. static void updateBIT(int BITree[], int n, int index, int val) { // Traverse all ancestors // and add 'val' while (index <= n) { // Add 'val' to current // node of BI Tree BITree[index] += val; // Update index to that of // parent in update View index += index & (-index); } } // Converts an array to an array // with values from 1 to n and // relative order of smaller and // greater elements remains same. // For example, {7, -90, 100, 1} // is converted to {3, 1, 4 ,2 } static void convert(int arr[], int n) { // Create a copy of arrp[] in temp // and sort the temp array in // increasing order int []temp = new int[n]; for (int i = 0; i < n; i++) temp[i] = arr[i]; Arrays.sort(temp); // Traverse all array elements for (int i = 0; i < n; i++) { // lower_bound() Returns pointer // to the first element greater // than or equal to arr[i] arr[i] =lower_bound(temp,0, n, arr[i]) + 1; } } static int lower_bound(int[] a, int low, int high, int element) { while(low < high) { int middle = low + (high - low) / 2; if(element > a[middle]) low = middle + 1; else high = middle; } return low; } // Returns inversion count // arr[0..n-1] static int getInvCount(int arr[], int n) { // Initialize result int invcount = 0; // Convert arr[] to an array // with values from 1 to n and // relative order of smaller // and greater elements remains // same. For example, {7, -90, // 100, 1} is converted to // {3, 1, 4 ,2 } convert(arr, n); // Create a BIT with size equal // to maxElement+1 (Extra one is // used so that elements can be // directly be used as index) int []BIT = new int[n + 1]; for (int i = 1; i <= n; i++) BIT[i] = 0; // Traverse all elements // from right. for (int i = n - 1; i >= 0; i--) { // Get count of elements // smaller than arr[i] invcount += getSum(BIT, arr[i] - 1); // Add current element to BIT updateBIT(BIT, n, arr[i], 1); } return invcount; } // 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 Amit Katiyar
Python3
# Python3 program to count inversions using Binary Indexed Tree from bisect import bisect_left as lower_bound # Returns sum of arr[0..index]. This function assumes # that the array is preprocessed and partial sums of # array elements are stored in BITree. def getSum(BITree, index): sum = 0 # Initialize result # Traverse ancestors of BITree[index] while (index > 0): # Add current element of BITree to sum sum += BITree[index] # Move index to parent node in getSum View index -= index & (-index) return sum # Updates a node in Binary Index Tree (BITree) at given index # in BITree. The given value 'val' is added to BITree[i] and # all of its ancestors in tree. def updateBIT(BITree, n, index, val): # Traverse all ancestors and add 'val' while (index <= n): # Add 'val' to current node of BI Tree BITree[index] += val # Update index to that of parent in update View index += index & (-index) # Converts an array to an array with values from 1 to n # and relative order of smaller and greater elements remains # same. For example, 7, -90, 100, 1 is converted to # 3, 1, 4 ,2 def convert(arr, n): # Create a copy of arrp in temp and sort the temp array # in increasing order temp = [0]*(n) for i in range(n): temp[i] = arr[i] temp = sorted(temp) # Traverse all array elements for i in range(n): # lower_bound() Returns pointer to the first element # greater than or equal to arr[i] arr[i] = lower_bound(temp, arr[i]) + 1 # Returns inversion count arr[0..n-1] def getInvCount(arr, n): invcount = 0 # Initialize result # Convert arr to an array with values from 1 to n and # relative order of smaller and greater elements remains # same. For example, 7, -90, 100, 1 is converted to # 3, 1, 4 ,2 convert(arr, n) # Create a BIT with size equal to maxElement+1 (Extra # one is used so that elements can be directly be # used as index) BIT = [0] * (n + 1) # Traverse all elements from right. for i in range(n - 1, -1, -1): # Get count of elements smaller than arr[i] invcount += getSum(BIT, arr[i] - 1) # Add current element to BIT updateBIT(BIT, n, arr[i], 1) return invcount # Driver program if __name__ == '__main__': arr = [8, 4, 2, 1] n = len(arr) print("Number of inversions are : ",getInvCount(arr, n)) # This code is contributed by mohit kumar 29
C#
// C# program to count inversions // using Binary Indexed Tree using System; class GFG{ // Returns sum of arr[0..index]. // This function assumes that the // array is preprocessed and partial // sums of array elements are stored // in BITree[]. static int getSum(int []BITree, int index) { // Initialize result int sum = 0; // Traverse ancestors of // BITree[index] while (index > 0) { // Add current element of // BITree to sum sum += BITree[index]; // Move index to parent node // in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index Tree // (BITree) at given index in BITree. // The given value 'val' is added to // BITree[i] and all of its ancestors // in tree. static void updateBIT(int []BITree, int n, int index, int val) { // Traverse all ancestors // and add 'val' while (index <= n) { // Add 'val' to current // node of BI Tree BITree[index] += val; // Update index to that of // parent in update View index += index & (-index); } } // Converts an array to an array // with values from 1 to n and // relative order of smaller and // greater elements remains same. // For example, {7, -90, 100, 1} // is converted to {3, 1, 4 ,2 } static void convert(int []arr, int n) { // Create a copy of arrp[] in temp // and sort the temp array in // increasing order int []temp = new int[n]; for (int i = 0; i < n; i++) temp[i] = arr[i]; Array.Sort(temp); // Traverse all array elements for (int i = 0; i < n; i++) { // lower_bound() Returns pointer // to the first element greater // than or equal to arr[i] arr[i] =lower_bound(temp,0, n, arr[i]) + 1; } } static int lower_bound(int[] a, int low, int high, int element) { while(low < high) { int middle = low + (high - low) / 2; if(element > a[middle]) low = middle + 1; else high = middle; } return low; } // Returns inversion count // arr[0..n-1] static int getInvCount(int []arr, int n) { // Initialize result int invcount = 0; // Convert []arr to an array // with values from 1 to n and // relative order of smaller // and greater elements remains // same. For example, {7, -90, // 100, 1} is converted to // {3, 1, 4 ,2 } convert(arr, n); // Create a BIT with size equal // to maxElement+1 (Extra one is // used so that elements can be // directly be used as index) int []BIT = new int[n + 1]; for (int i = 1; i <= n; i++) BIT[i] = 0; // Traverse all elements // from right. for (int i = n - 1; i >= 0; i--) { // Get count of elements // smaller than arr[i] invcount += getSum(BIT, arr[i] - 1); // Add current element // to BIT updateBIT(BIT, n, arr[i], 1); } return invcount; } // 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 Amit Katiyar
Javascript
<script> // Javascript program to count inversions // using Binary Indexed Tree // Returns sum of arr[0..index]. // This function assumes that the // array is preprocessed and partial // sums of array elements are stored // in BITree[]. function getSum(BITree,index) { // Initialize result let sum = 0; // Traverse ancestors of // BITree[index] while (index > 0) { // Add current element of // BITree to sum sum += BITree[index]; // Move index to parent node // in getSum View index -= index & (-index); } return sum; } // Updates a node in Binary Index Tree // (BITree) at given index in BITree. // The given value 'val' is added to // BITree[i] and all of its ancestors // in tree. function updateBIT(BITree,n,index,val) { // Traverse all ancestors // and add 'val' while (index <= n) { // Add 'val' to current // node of BI Tree BITree[index] += val; // Update index to that of // parent in update View index += index & (-index); } } // Converts an array to an array // with values from 1 to n and // relative order of smaller and // greater elements remains same. // For example, {7, -90, 100, 1} // is converted to {3, 1, 4 ,2 } function convert(arr, n) { // Create a copy of arrp[] in temp // and sort the temp array in // increasing order let temp = new Array(n); for (let i = 0; i < n; i++) temp[i] = arr[i]; temp.sort(function(a, b){return a - b;}); // Traverse all array elements for (let i = 0; i < n; i++) { // lower_bound() Returns pointer // to the first element greater // than or equal to arr[i] arr[i] =lower_bound(temp,0, n, arr[i]) + 1; } } function lower_bound(a,low,high,element) { while(low < high) { let middle = low + Math.floor((high - low) / 2); if(element > a[middle]) low = middle + 1; else high = middle; } return low; } // Returns inversion count // arr[0..n-1] function getInvCount(arr,n) { // Initialize result let invcount = 0; // Convert arr[] to an array // with values from 1 to n and // relative order of smaller // and greater elements remains // same. For example, {7, -90, // 100, 1} is converted to // {3, 1, 4 ,2 } convert(arr, n); // Create a BIT with size equal // to maxElement+1 (Extra one is // used so that elements can be // directly be used as index) let BIT = new Array(n + 1); for (let i = 1; i <= n; i++) BIT[i] = 0; // Traverse all elements // from right. for (let i = n - 1; i >= 0; i--) { // Get count of elements // smaller than arr[i] invcount += getSum(BIT, arr[i] - 1); // Add current element to BIT updateBIT(BIT, n, arr[i], 1); } return invcount; } // Driver code let arr=[8, 4, 2, 1]; let n = arr.length; document.write("Number of inversions are : " + getInvCount(arr, n)); // This code is contributed by unknown2108 </script>
Number of inversions are : 6
Complejidad de tiempo: la función de actualización y la función getSum se ejecutan para O (log (n)). La función getSum debe ejecutarse para cada elemento de la array. Entonces, la complejidad del tiempo general es O (nlog (n)).
Espacio Auxiliar: O(n).
El espacio requerido para el BIT es una array de tamaño n.
Este artículo es una contribución de Abhiraj Smit. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA