Skip to content

Instantly share code, notes, and snippets.

@rewonc
Last active December 21, 2018 12:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rewonc/62b40c5f2f7f67ffa928 to your computer and use it in GitHub Desktop.
Save rewonc/62b40c5f2f7f67ffa928 to your computer and use it in GitHub Desktop.
Counting array inversions in Javascript
function countInversions(array){
// Note: this uses a variant of merge sort
//input handlers
if (array === undefined) throw new Error("Array must be defined to count inversions");
if (array.length === 0 || array.length === 1) return 0;
var tally = 0; // count for inversions
sort(array); // merge sort the array and increment tally when there are crossovers
return tally;
function sort(arr) {
if (arr.length === 1) return arr;
var right = arr.splice(Math.floor(arr.length/2), arr.length - 1);
return merge(sort(arr), sort(right));
}
function merge(left, right){
var merged = [];
var l = 0, r = 0;
var multiplier = 0;
while (l < left.length || r < right.length){
if (l === left.length){
merged.push(right[r]);
r++;
} else if (r === right.length){
merged.push(left[l]);
l++;
tally += multiplier;
} else if (left[l] < right[r]) {
merged.push(left[l]);
tally += multiplier;
l++;
} else {
merged.push(right[r]);
r++;
multiplier++;
}
}
return merged;
}
}
//tests to run in console
/*
console.assert(countInversions([1, 2, 3]) === 0, "Zero inversions for 1, 2, 3");
console.assert(countInversions([1, 3, 2]) === 1, "One inversion for 1, 3, 2");
console.assert(countInversions([1, 3, 2, 4]) === 1, "One inversion for 1, 3, 2, 4");
console.assert(countInversions([1, 3, 2, 4, 5]) === 1, "One inversions for 1, 3, 2, 4, 5");
console.assert(countInversions([3, 1, 2, 4, 5]) === 2, "Two inversions for 3, 1, 2, 4, 5");
console.assert(countInversions([3, 2, 1, 4, 5]) === 3, "Three inversions for 3, 2, 1, 4, 5");
console.assert(countInversions([3, 2, 1, 4, 5, 6]) === 3, "Three inversions for 3, 2, 1, 4, 5, 6");
console.assert(countInversions([6, 5, 4, 3, 2, 1]) === 15, "Fifteen inversions for 654321");
*/
@usmanajmal
Copy link

usmanajmal commented Mar 10, 2018

Good solution but you can simplify it a bit by getting rid of tally variable altogether.
Way to do that is just have:

multiplier += (left.length - l)

instead of multiplier++ on Line 37.

Idea here is that number of inversions = Number of elements to the right of current index (l) of left array. Also, I will advise to rename multiplier with just inversions or num_inversions.

@acierto
Copy link

acierto commented Nov 15, 2018

Doesn't work properly, try on this array: [2, 3, 9, 2, 9]
Should be 2, actual result 4.

The two inversions here are (1, 3) (a1 = 3 > 2 = a3) and (2, 3) (a2 = 9 > 2 = a3).

@saeedafroozi
Copy link

Dear Doesn't Work Properly, for example in this case:[1,3,1,2]
Expected is :2
but the result is:3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment