class CountInversions {
// Merge two sorted halves and count cross inversions
merge(arr, temp, left, mid, right) {
let i = left, j = mid + 1, k = left;
let inv_count = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++]; // take from left half
} else {
temp[k++] = arr[j++]; // take from right half
inv_count += (mid - i + 1); // count inversions
}
}
while (i <= mid) temp[k++] = arr[i++]; // copy remaining left
while (j <= right) temp[k++] = arr[j++]; // copy remaining right
for (let idx = left; idx <= right; idx++) arr[idx] = temp[idx]; // copy back
return inv_count;
}
// Recursive function to count inversions
mergeSort(arr, temp, left, right) {
let inv_count = 0;
if (left < right) {
let mid = Math.floor((left + right) / 2);
inv_count += this.mergeSort(arr, temp, left, mid); // left half
inv_count += this.mergeSort(arr, temp, mid + 1, right); // right half
inv_count += this.merge(arr, temp, left, mid, right); // merge and count
}
return inv_count;
}
countInversions(arr) {
let temp = new Array(arr.length);
return this.mergeSort(arr, temp, 0, arr.length - 1);
}
}
// Driver code
const arr = [2, 4, 1, 3, 5];
const counter = new CountInversions();
const result = counter.countInversions(arr);
console.log("Sorted array:", arr.join(" -> "));
console.log("Total inversions:", result);if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; inv_count += (mid - i + 1); }
merge step: count inversions when right element is smaller than left
inv_count += this.mergeSort(arr, temp, left, mid); inv_count += this.mergeSort(arr, temp, mid + 1, right); inv_count += this.merge(arr, temp, left, mid, right);
recursive divide and conquer: count inversions in left, right, and merged parts
Sorted array: 1 -> 2 -> 3 -> 4 -> 5
Total inversions: 3