📌  相关文章
📜  用于计算给定数组中大小为 3 的倒数的Java程序

📅  最后修改于: 2022-05-13 01:54:26.775000             🧑  作者: Mango

用于计算给定数组中大小为 3 的倒数的Java程序

给定一个大小为 n 的数组 arr[]。如果 a[i] > a[j] >a[k] 并且 i < j < k,则三个元素 arr[i]、arr[j] 和 arr[k] 形成大小为 3 的反转。求大小为 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}

我们已经通过归并排序、自平衡 BST 和 BIT 讨论了大小为 2 的反转计数。
简单的方法:-循环 i、j 和 k 的所有可能值并检查条件 a[i] > a[j] > a[k] 和 i < j < k。

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 arr[j])
                {
                    for(int k=j+1; k 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


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 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


输出:

Inversion Count : 4 

这种方法的时间复杂度是:O(n^3)
更好的方法:
如果我们将每个元素 arr[i] 视为求逆的中间元素,我们可以降低复杂度,找出所有大于 a[i] 且索引小于 i 的数,找出所有小于 a[i] 的数并指数大于 i。我们将大于 a[i] 的元素数乘以小于 a[i] 的元素数并将其添加到结果中。
下面是这个想法的实现。

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 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

输出 :

Inversion Count : 4 

这种方法的时间复杂度:O(n^2)
二叉索引树方法:
与大小为 2 的反转一样,我们可以使用二叉索引树来查找大小为 3 的反转。强烈建议先参考下面的文章。
使用 BIT 计算大小为 2 的反转
思路与上述方法类似。我们计算所有元素的更大元素和更小元素的数量,然后将更大的[]乘以更小的[]并将其添加到结果中。
解决方案 :

  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] 的元素数。

有关更多详细信息,请参阅有关给定数组中大小为 3 的计数反转的完整文章!