Python Program to Count Inversions in an array

In this article, we will learn about counting inversions in an array. An inversion occurs when a larger element appears before a smaller element in an array.

Problem statement ? We are given an array, we need to count the total number of inversions and display it.

Inversion count represents how far an array is from being sorted. For example, in array [2, 3, 8, 6, 1], the pairs (2,1), (3,1), (8,6), (8,1), and (6,1) are inversions.

What is an Inversion?

An inversion is a pair of indices (i, j) where i < j but arr[i] > arr[j]. In other words, a larger element comes before a smaller element.

Array: [1, 5, 3, 8, 7] 1 i=0 5 i=1 3 i=2 8 i=3 7 i=4 5 > 3 8 > 7 Inversions found: (5,3) and (8,7) Total inversions: 2

Using Nested Loops (Brute Force)

The simplest approach is to check every pair of elements and count inversions ?

def count_inversions(arr):
    n = len(arr)
    inv_count = 0
    
    for i in range(n):
        for j in range(i + 1, n):
            if arr[i] > arr[j]:
                inv_count += 1
    
    return inv_count

# Example usage
numbers = [1, 5, 3, 8, 7]
result = count_inversions(numbers)
print("Array:", numbers)
print("Total inversions:", result)
Array: [1, 5, 3, 8, 7]
Total inversions: 2

Step-by-Step Execution

Let's trace through the algorithm with array [1, 5, 3, 8, 7] ?

def count_inversions_detailed(arr):
    n = len(arr)
    inv_count = 0
    print(f"Checking array: {arr}")
    
    for i in range(n):
        for j in range(i + 1, n):
            if arr[i] > arr[j]:
                print(f"Inversion found: arr[{i}] = {arr[i]} > arr[{j}] = {arr[j]}")
                inv_count += 1
            else:
                print(f"No inversion: arr[{i}] = {arr[i]} <= arr[{j}] = {arr[j]}")
    
    return inv_count

# Detailed execution
numbers = [1, 5, 3, 8, 7]
result = count_inversions_detailed(numbers)
print(f"\nTotal inversions: {result}")
Checking array: [1, 5, 3, 8, 7]
No inversion: arr[0] = 1 <= arr[1] = 5
No inversion: arr[0] = 1 <= arr[2] = 3
No inversion: arr[0] = 1 <= arr[3] = 8
No inversion: arr[0] = 1 <= arr[4] = 7
Inversion found: arr[1] = 5 > arr[2] = 3
No inversion: arr[1] = 5 <= arr[3] = 8
No inversion: arr[1] = 5 <= arr[4] = 7
No inversion: arr[2] = 3 <= arr[3] = 8
No inversion: arr[2] = 3 <= arr[4] = 7
Inversion found: arr[3] = 8 > arr[4] = 7

Total inversions: 2

Testing Different Arrays

Let's test the function with various arrays to understand the concept better ?

def count_inversions(arr):
    n = len(arr)
    inv_count = 0
    
    for i in range(n):
        for j in range(i + 1, n):
            if arr[i] > arr[j]:
                inv_count += 1
    
    return inv_count

# Test cases
test_arrays = [
    [1, 2, 3, 4, 5],     # Already sorted
    [5, 4, 3, 2, 1],     # Reverse sorted
    [2, 3, 8, 6, 1],     # Random array
    [1, 1, 1, 1],        # All same elements
]

for arr in test_arrays:
    inversions = count_inversions(arr)
    print(f"Array: {arr} ? Inversions: {inversions}")
Array: [1, 2, 3, 4, 5] ? Inversions: 0
Array: [5, 4, 3, 2, 1] ? Inversions: 10
Array: [2, 3, 8, 6, 1] ? Inversions: 5
Array: [1, 1, 1, 1] ? Inversions: 0

Time and Space Complexity

Aspect Brute Force Optimized (Merge Sort)
Time Complexity O(n²) O(n log n)
Space Complexity O(1) O(n)
Best For Small arrays Large arrays

Conclusion

Inversion count measures how far an array is from being sorted. The brute force O(n²) approach works well for small arrays, while merge sort-based solutions are more efficient for larger datasets.

Updated on: 2026-03-25T06:54:47+05:30

316 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements