Python Program to Count Inversions of Size Three in A Given Array

An inversion of size three in an array occurs when three elements at indices i < j < k satisfy arr[i] > arr[j] > arr[k]. This is different from regular inversions which only consider pairs. Let's explore three approaches to count such inversions efficiently.

Understanding Inversions of Size Three

For an array to have an inversion of size three, we need three elements in decreasing order but with increasing indices ?

Array: [8, 4, 2, 1]
Inversions of size 3: (8,4,2), (8,4,1), (8,2,1), (4,2,1)
Count: 4

Array: [1, 2, 3, 4]  // sorted array
Inversions of size 3: None
Count: 0

Method 1: Brute Force Approach

Check all possible triplets with three nested loops ?

def getInvCount(arr):
    n = len(arr)
    invcount = 0
    
    for i in range(n-2):
        for j in range(i+1, n-1):
            if arr[i] > arr[j]:
                for k in range(j+1, n):
                    if arr[j] > arr[k]:
                        invcount += 1
    return invcount

arr = [8, 4, 2, 1]
print("Inversion Count:", getInvCount(arr))
Inversion Count: 4

Method 2: Optimized Approach

Consider each element as the middle element and count smaller/greater elements ?

def getInvCount(arr):
    n = len(arr)
    invcount = 0
    
    # Consider each element as middle element
    for i in range(1, n-1):
        # Count smaller elements on the right
        smaller_right = 0
        for j in range(i+1, n):
            if arr[i] > arr[j]:
                smaller_right += 1
        
        # Count greater elements on the left
        greater_left = 0
        for j in range(i):
            if arr[j] > arr[i]:
                greater_left += 1
        
        # Multiply counts to get inversions through this middle element
        invcount += greater_left * smaller_right
    
    return invcount

arr = [8, 4, 2, 1]
print("Inversion Count:", getInvCount(arr))
Inversion Count: 4

Method 3: Using Binary Indexed Tree

Use a Binary Indexed Tree for efficient range queries and updates ?

def getSum(BITree, index):
    sum_val = 0
    while index > 0:
        sum_val += BITree[index]
        index -= index & (-index)
    return sum_val

def updateBIT(BITree, n, index, val):
    while index <= n:
        BITree[index] += val
        index += index & (-index)

def getInvCountBIT(arr):
    n = len(arr)
    invcount = 0
    maxElement = max(arr)
    
    # Create Binary Indexed Tree
    BIT = [0] * (maxElement + 1)
    
    # Process elements from right to left
    for i in range(n-1, -1, -1):
        # Get count of smaller elements processed so far
        invcount += getSum(BIT, arr[i] - 1)
        # Update BIT with current element
        updateBIT(BIT, maxElement, arr[i], 1)
    
    return invcount

# Note: This counts all inversions, not just size 3
arr = [8, 4, 2, 1]
print("Total Inversions:", getInvCountBIT(arr))
Total Inversions: 6

Comparison

Method Time Complexity Space Complexity Best For
Brute Force O(n³) O(1) Small arrays
Middle Element O(n²) O(1) Medium arrays
Binary Indexed Tree O(n log n) O(max_element) Large arrays

Conclusion

For counting inversions of size three, the optimized O(n²) approach using middle elements is most practical. The Binary Indexed Tree method works best for counting all inversions efficiently in large datasets.

Updated on: 2026-03-27T00:56:59+05:30

756 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements