Counting Inversions
Problem Statement
Input. Array A containing numbers 1,2,3,... in some arbitrary order.
Output. No. of inversions.
Example. 1, 3, 5, 2, 4, 6
Inversions. (3, 2) (5, 2) (5, 4)
1 2 3 4 5

\/ \/

/\ /\
 / \/ \
 /
/\
\
1 3 5 2 4
6




6
Motivation.
Numerical similarity between two ranked lists.
Applications.
Find similar preferences between movies listed by two friends.
Colaborative filtering. recommendation based on purchases made by similar buyers.
Q. Largest possible No. of inversions for a six element array.
!
n(n 1)
n
=
2
2
Worst case. array in backward order.
Algorithm 1. Bruteforce
Basic Idea. Compare each element to the rest of the elements similar to bubble sort.
Running time. T (n) = O(n2 )
Goal. Can we do better?
1
Algorithm 2.
Divide and Conquer
Definition. Inversion (i, j) if A[i] > A[j] with i < j.
Types of inversions.
lef t if (i, j) n2
split if i n < j
2
After recursive calls, it requires residual task of collecting the results from all calls.
Pseudocode.
Count ( Array A, Length n )
IF n == 1 THEN return 0
ELSE
X = Count(1st half of A, \frac{n}{2})
Y = Count(2nd half of A, \frac{n}{2})
Z = CountSplit (A, n)
return X + Y + Z
Our Goal. O(nlogn) if we solve CountSplit in linear time. This is ambitious as counting
inversions takes quadratic time, if all the inversions are split (the case in previous example).
Can we do better?
3
C =
D =
D =
D =
D =
_________
___ ___ ___




 2  4  6 
_________
___ ___ ___ ___ ___ ___







 1 





__________________
___ ___ ___ ___ ___ ___







 1  2 




__________________
___ ___ ___ ___ ___ ___







 1  2  3 



__________________
___ ___ ___ ___ ___ ___







 1  2  3  4 


__________________
and so on.
q
q
Pseudocode.
[D,Z] = CountSplitMerge(A,B,C,n)
q
q
While merge sorted arrays B,C; keep running total of number of split inversions.
When element from C gets copied to output D, increment Z with number of elements
right of i in B.
Running Time.
T (n) = merge + count
= n+n
= O(n)