🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 计算给定数组中大小为 3 的反转 > 原文: [https://www.geeksforgeeks.org/count-inversions-of-size-three-in-a-give-array/](https://www.geeksforgeeks.org/count-inversions-of-size-three-in-a-give-array/) 给定大小为 n 的数组 arr []。 如果 a [i] > a [j] > a [k]和 i < j <,则三个元素 arr [i],arr [j]和 arr [k]形成大小为 3 的反转。 k。 查找大小为 3 的反演总数。 **示例**: ``` Input: {8, 4, 2, 1} Output: 4 The four inversions are (8,4,2), (8,4,1), (4,2,1) and (8,2,1). Input: {9, 6, 4, 5, 8} Output: 2 The two inversions are {9, 6, 4} and {9, 6, 5} ``` 我们已经讨论了通过[合并排序](https://www.geeksforgeeks.org/counting-inversions/),[自平衡 BST](https://www.geeksforgeeks.org/count-inversions-in-an-array-set-2-using-self-balancing-bst/) 和 [BIT](https://www.geeksforgeeks.org/count-inversions-array-set-3-using-bit/) 进行的大小为 2 的反转计数。 **简单方法:-**循环搜索 i,j 和 k 的所有可能值,并检查条件 a [i] > a [j] > a [k]和 i < j < k。 ## C++ ```cpp // A Simple C++ O(n^3)  program to count inversions of size 3 #include<bits/stdc++.h> using namespace std; // Returns counts of inversions of size three int getInvCount(int arr[],int n) {     int invcount = 0;  // Initialize result     for (int i=0; i<n-2; i++)     {         for (int j=i+1; j<n-1; j++)         {             if (arr[i]>arr[j])             {                 for (int k=j+1; k<n; k++)                 {                     if (arr[j]>arr[k])                         invcount++;                 }             }         }     }     return invcount; } // Driver program to test above function int main() {     int arr[] = {8, 4, 2, 1};     int n = sizeof(arr)/sizeof(arr[0]);     cout << "Inversion Count : " << getInvCount(arr, n);     return 0; } ``` ## Java ```java // A simple Java implementation  to count inversion of size 3 class Inversion{     // returns count of inversion of size 3     int getInvCount(int arr[], int n)     {         int invcount = 0; // initialize result         for(int i=0 ; i< n-2; i++)         {             for(int j=i+1; j<n-1; j++)             {                 if(arr[i] > arr[j])                 {                     for(int k=j+1; k<n; k++)                     {                         if(arr[j] > arr[k])                             invcount++;                     }                 }             }         }         return invcount;     }     // driver program to test above function     public static void main(String args[])     {         Inversion inversion = new Inversion();         int arr[] = new int[] {8, 4, 2, 1};         int n = arr.length;         System.out.print("Inversion count : " +                      inversion.getInvCount(arr, n));     } } // This code is contributed by Mayank Jaiswal ``` ## Python ``` # A simple python O(n^3) program # to count inversions of size 3 # Returns counts of inversions # of size threee def getInvCount(arr):     n = len(arr)     invcount = 0  #Initialize result         for i in range(0,n-1):         for j in range(i+1 , n):                 if arr[i] > arr[j]:                     for k in range(j+1 , n):                         if arr[j] > arr[k]:                             invcount += 1     return invcount # Driver program to test above function arr = [8 , 4, 2 , 1] print "Inversion Count : %d" %(getInvCount(arr)) # This code is contributed by Nikhil Kumar Singh(nickzuck_007) ``` ## C# ```cs // A simple C# implementation to // count inversion of size 3 using System; class GFG { // returns count of inversion of size 3 static int getInvCount(int []arr, int n)     {         // initialize result         int invcount = 0;          for(int i = 0 ; i < n - 2; i++)         {             for(int j = i + 1; j < n - 1; j++)             {                 if(arr[i] > arr[j])                 {                     for(int k = j + 1; k < n; k++)                     {                         if(arr[j] > arr[k])                             invcount++;                     }                 }             }         }         return invcount;     }     // Driver Code     public static void Main()     {         int []arr = new int[] {8, 4, 2, 1};         int n = arr.Length;         Console.WriteLine("Inversion count : " +                             getInvCount(arr, n));     } } // This code is contributed by anuj_67\. ``` ## PHP ```php <?php // A O(n^2) PHP program to  // count inversions of size 3 // Returns count of  // inversions of size 3 function getInvCount($arr, $n) {     // Initialize result     $invcount = 0;      for ($i = 1; $i < $n - 1; $i++)     {         // Count all smaller elements          // on right of arr[i]         $small = 0;         for($j = $i + 1; $j < $n; $j++)             if ($arr[$i] > $arr[$j])                 $small++;         // Count all greater elements          // on left of arr[i]         $great = 0;         for($j = $i - 1; $j >= 0; $j--)             if ($arr[$i] < $arr[$j])                 $great++;         // Update inversion count by          // adding all inversions         // that have arr[i] as          // middle of three elements         $invcount += $great * $small;     }     return $invcount; }     // Driver Code     $arr = array(8, 4, 2, 1);     $n = sizeof($arr);     echo "Inversion Count : "         , getInvCount($arr, $n); // This code is contributed m_kit ?> ``` Output: ``` Inversion Count : 4 ``` **这种方法的时间复杂度**为:O(n ^ 3) **更好的方法**: 如果我们将每个元素 arr [i]视为反演的中间元素,并找到所有大于 a [i]且其索引大的数字,则可以降低复杂度 小于 i,找到所有小于 a [i]且索引大于 i 的数字。 我们将大于 a [i]的元素数量乘以小于 a [i]的元素数量,并将其添加到结果中。 以下是该想法的实现。 ## C++ ``` // A O(n^2) C++  program to count inversions of size 3 #include<bits/stdc++.h> using namespace std; // Returns count of inversions of size 3 int getInvCount(int arr[], int n) {     int invcount = 0;  // Initialize result     for (int i=1; i<n-1; i++)     {         // Count all smaller elements on right of arr[i]         int small = 0;         for (int j=i+1; j<n; j++)             if (arr[i] > arr[j])                 small++;         // Count all greater elements on left of arr[i]         int great = 0;         for (int j=i-1; j>=0; j--)             if (arr[i] < arr[j])                 great++;         // Update inversion count by adding all inversions         // that have arr[i] as middle of three elements         invcount += great*small;     }     return invcount; } // Driver program to test above function int main() {     int arr[] = {8, 4, 2, 1};     int n = sizeof(arr)/sizeof(arr[0]);     cout << "Inversion Count : " << getInvCount(arr, n);     return 0; } ``` ## Java ```java // A O(n^2) Java  program to count inversions of size 3 class Inversion {     // returns count of inversion of size 3     int getInvCount(int arr[], int n)     {         int invcount = 0; // initialize result         for (int i=0 ; i< n-1; i++)         {             // count all smaller elements on right of arr[i]             int small=0;             for (int j=i+1; j<n; j++)                 if (arr[i] > arr[j])                     small++;             // count all greater elements on left of arr[i]             int great = 0;             for (int j=i-1; j>=0; j--)                         if (arr[i] < arr[j])                             great++;             // update inversion count by adding all inversions             // that have arr[i] as middle of three elements             invcount += great*small;         }         return invcount;     }     // driver program to test above function     public static void main(String args[])     {         Inversion inversion = new Inversion();         int arr[] = new int[] {8, 4, 2, 1};         int n = arr.length;         System.out.print("Inversion count : " +                        inversion.getInvCount(arr, n));     } } // This code has been contributed by Mayank Jaiswal ``` ## Python3 ```py # A O(n^2) Python3 program to #  count inversions of size 3 # Returns count of inversions # of size 3 def getInvCount(arr, n):     # Initialize result     invcount = 0        for i in range(1,n-1):         # Count all smaller elements         # on right of arr[i]         small = 0         for j in range(i+1 ,n):             if (arr[i] > arr[j]):                 small+=1         # Count all greater elements         # on left of arr[i]         great = 0;         for j in range(i-1,-1,-1):             if (arr[i] < arr[j]):                 great+=1         # Update inversion count by         # adding all inversions that         # have arr[i] as middle of         # three elements         invcount += great * small     return invcount # Driver program to test above function arr = [8, 4, 2, 1] n = len(arr) print("Inversion Count :",getInvCount(arr, n)) # This code is Contributed by Smitha Dinesh Semwal ``` ## C# ``` // A O(n^2) Java program to count inversions // of size 3 using System; public class Inversion {     // returns count of inversion of size 3     static int getInvCount(int []arr, int n)     {         int invcount = 0; // initialize result         for (int i = 0 ; i < n-1; i++)         {             // count all smaller elements on              // right of arr[i]             int small = 0;             for (int j = i+1; j < n; j++)                 if (arr[i] > arr[j])                     small++;             // count all greater elements on             // left of arr[i]             int great = 0;             for (int j = i-1; j >= 0; j--)                         if (arr[i] < arr[j])                             great++;             // update inversion count by              // adding all inversions that              // have arr[i] as middle of             // three elements             invcount += great * small;         }         return invcount;     }     // driver program to test above function     public static void Main()     {         int []arr = new int[] {8, 4, 2, 1};         int n = arr.Length;         Console.WriteLine("Inversion count : "                        + getInvCount(arr, n));     } } // This code has been contributed by anuj_67\. ``` ## PHP ```php <?php // A O(n^2) PHP program to count // inversions of size 3 // Returns count of  // inversions of size 3 function getInvCount($arr, $n) {     // Initialize result     $invcount = 0;      for ($i = 1; $i < $n - 1; $i++)     {         // Count all smaller elements         // on right of arr[i]         $small = 0;         for ($j = $i + 1; $j < $n; $j++)             if ($arr[$i] > $arr[$j])                 $small++;         // Count all greater elements         // on left of arr[i]         $great = 0;         for ($j = $i - 1; $j >= 0; $j--)             if ($arr[$i] < $arr[$j])                 $great++;         // Update inversion count by          // adding all inversions that         // have arr[i] as middle of          // three elements         $invcount += $great * $small;     }     return $invcount; } // Driver Code $arr = array (8, 4, 2, 1); $n = sizeof($arr); echo "Inversion Count : " ,        getInvCount($arr, $n); // This code is contributed by m_kit ?> ``` **输出**: ``` Inversion Count : 4 ``` **这种方法的时间复杂度**:O(n ^ 2) **二元索引树方法**: 与大小为 2 的反转类似,我们可以使用二进制索引树来找到大小为 3 的反转。强烈建议首先参考以下文章。 [使用 BIT 计数大小为 2 的反转](https://www.geeksforgeeks.org/count-inversions-array-set-3-using-bit/) 这个想法类似于上面的方法。 我们计算所有元素的较大元素和较小元素的数量,然后将 great []乘以 small []并将其添加到结果中。 **解决方案**: 1. 为了找出索引中较小元素的数量,我们从 n-1 迭代到 0。对于每个元素 a [i],我们计算(a [i] -1)的 getSum()函数,该函数给出元素的数量直到 a [i] -1。 2. 为了找出索引中更大元素的数量,我们从 0 迭代到 n-1。 对于每个元素 a [i],我们通过 getSum()计算直到 a [i]的数目之和(总和小于或等于 a [i]),然后从 i 中减去它(因为 i 是该点之前元素的总数) ),这样我们就可以得到大于 a [i]的元素数量。 就像我们对大小为 2 的[反转所做的一样,这里我们还将输入数组转换为值从 1 到 n 的数组,以便 BIT 的大小保持为`O(n)`,并且 getSum()和 update( )函数需要`O(log n)`时间。 例如,我们将 arr [] = {7,-90,100,1}转换为 arr [] = {3,1,4,2}。](https://www.geeksforgeeks.org/count-inversions-array-set-3-using-bit/) 以下是上述想法的实现。 ## C ``` // C++ program to count inversions of size three 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 count of inversions of size three int getInvCount(int arr[], int n) {     // 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 and initialize smaller and greater arrays     int greater1[n], smaller1[n];     for (int i=0; i<n; i++)         greater1[i] = smaller1[i] = 0;     // Create and initialize an array to store Binary     // Indexed Tree     int BIT[n+1];     for (int i=1; i<=n; i++)         BIT[i]=0;     for(int i=n-1; i>=0; i--)     {         smaller1[i] = getSum(BIT, arr[i]-1);         updateBIT(BIT, n, arr[i], 1);     }     // Reset BIT     for (int i=1; i<=n; i++)         BIT[i] = 0;     // Count greater elements     for (int i=0; i<n; i++)     {         greater1[i] = i - getSum(BIT,arr[i]);         updateBIT(BIT, n, arr[i], 1);     }     // Compute Inversion count using smaller[] and     // greater[].      int invcount = 0;     for (int i=0; i<n; i++)         invcount += smaller1[i]*greater1[i];     return invcount; } // Driver program to test above function int main() {     int arr[] = {8, 4, 2, 1};     int n = sizeof(arr)/sizeof(arr[0]);     cout << "Inversion Count : " << getInvCount(arr, n);     return 0; } ```