📜  计算给定数组中大小为3的反转

📅  最后修改于: 2021-04-17 11:44:16             🧑  作者: Mango

给定大小为n的数组arr []。如果a [i]> a [j]> a [k]且i 例子 :

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

C++
// A Simple C++ O(n^3)  program to count inversions of size 3
#include
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; iarr[j])
            {
                for (int k=j+1; karr[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
// 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


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#
// 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
 $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
?>


Javascript


C++
// A O(n^2) C++  program to count inversions of size 3
#include
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 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
// 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


Python3
# 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
 $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
?>


Javascript


输出:

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

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

Python3

# 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

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

Java脚本


输出 :

Inversion Count : 4 

这种方法的时间复杂度:O(n ^ 2)
二叉索引树法:
像大小为2的反转一样,我们可以使用二进制索引树查找大小为3的反转。强烈建议首先参考下面的文章。
使用BIT计算大小为2的反转
这个想法类似于上面的方法。我们计算所有元素的较大元素和较小元素的数量,然后将Greater []乘以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]的元素数量。