The algorithm you are looking for is called Counting inversions. Yes you can solve this problem using divide and conquer approach and the time complexity will be O(nlogn). It's similar to merge sort and additionally we need to keep track of inversions count. I am only printing the inversions count.
public class InversionsInOrderNSquared {
public static void main(String[] args) {
int array[] = { 10, 15, 2, 2, -4, 100, 99999, -10 };
System.out.println("Inversions Count: "+inversions(array));
}
private static int inversions(int[] array) {
int n = array.length;
int inversionCountLeft = 0;
int inversionCountRight = 0;
int inversionCountCross = 0;
if (n >= 2) {
int mid = n / 2;
int[] leftArray = new int[mid];
int[] rightArray = new int[n - mid];
for (int i = 0; i < n; i++) {
if (i < mid) {
leftArray[i] = array[i];
} else {
rightArray[i - mid] = array[i];
}
}
inversionCountLeft = inversions(leftArray);
inversionCountRight = inversions(rightArray);
inversionCountCross = computeInversions(array, leftArray,
rightArray);
}
return (inversionCountLeft + inversionCountRight + inversionCountCross);
}
private static int computeInversions(int[] array, int[] leftArray,
int[] rightArray) {
int n_left = leftArray.length;
int n_right = rightArray.length;
int inversionCount = 0;
int i = 0;
int j = 0;
int k = 0;
while (i < n_left && j < n_right) {
if (leftArray[i] > rightArray[j]) {
array[k] = rightArray[j];
inversionCount += (n_left - i);// logic is we are doing index
// wise element comparison
// between 2 sorted arrays thus
// for any index if any element
// in left
// sub-array is grater than
// element in right sub array
// that mean all the elements
// after that element present in
// left sub-array should be
// grater than right sub-array
// elements. Thus we are
// considering (n_left - i) in
// inversion count calculation.
j++;
} else {
array[k] = leftArray[i];
i++;
}
k++;
}
while (i < n_left) {
array[k] = leftArray[i];
i++;
k++;
}
while (j < n_right) {
array[k] = rightArray[j];
j++;
k++;
}
return inversionCount;
}
}
Execution 1:
Output:
Input array:
int array[] = { 10, 15, 2, 2, -4, 100, 99999, -10 };
Inversions Count: 15
Execution 2:
Input array:
int array[] = { 1,2,3,4,5,6 };
Output:
Inversions Count: 0
Regarding time complexity calculation:
computeInversions() method will take theta(n) time.
inversions() method is getting called 2 times with array size n/2.
Hence the recurrence relation is,
T(n) = 2T(n/2) + theta(n);
It's following Master's theorem equation format.
Hence a =2, b=2 and f(n)=theta(n)
n^log a base b = n^log 2 base 2 = n^1 = n
Thus above recurrence is matching case 2 of Master's theorem.
Thus time complexity is O(nlogn)