package main
import "fmt"
func merge(arr []int, temp []int, left int, mid int, right int) int {
i := left
j := mid + 1
k := left
invCount := 0
for i <= mid && j <= right {
if arr[i] <= arr[j] {
temp[k] = arr[i]
i++
k++
} else {
temp[k] = arr[j]
invCount += (mid - i + 1) // count inversions
j++
k++
}
}
for i <= mid {
temp[k] = arr[i]
i++
k++
}
for j <= right {
temp[k] = arr[j]
j++
k++
}
for idx := left; idx <= right; idx++ {
arr[idx] = temp[idx]
}
return invCount
}
func mergeSort(arr []int, temp []int, left int, right int) int {
invCount := 0
if left < right {
mid := (left + right) / 2
invCount += mergeSort(arr, temp, left, mid) // sort left half
invCount += mergeSort(arr, temp, mid+1, right) // sort right half
invCount += merge(arr, temp, left, mid, right) // merge and count inversions
}
return invCount
}
func countInversions(arr []int) int {
temp := make([]int, len(arr))
return mergeSort(arr, temp, 0, len(arr)-1)
}
func main() {
arr := []int{2, 4, 1, 3, 5}
inversions := countInversions(arr)
fmt.Printf("Sorted array: %v\n", arr)
fmt.Printf("Total inversions: %d\n", inversions)
}
compare elements to decide which goes first in merged array
invCount += (mid - i + 1) // count inversions
count how many elements left in left half are greater than arr[j]
invCount += mergeSort(arr, temp, left, mid) // sort left half
recursively count inversions in left half
invCount += mergeSort(arr, temp, mid+1, right) // sort right half
recursively count inversions in right half
invCount += merge(arr, temp, left, mid, right) // merge and count inversions
merge two halves and count cross inversions
Sorted array: [1 2 3 4 5]
Total inversions: 3