Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
