788. 逆序对的数量

788. 逆序对的数量

核心思路:在归并排序的基础上添加逆序对数量的求和,分三种情况

  • L区间左侧的数据L[i]>右侧数据L[j],逆序对数量=满足条件的数量
  • R区间左侧的数据R[i]>右侧数据R[j],逆序对数量=满足条件数量
  • R区间数据L[i]>L区间数据R[j] ,逆序对数量 = mid - i + 1

但其实代码中只添加了第三种情况的代码,因为对每个递归出的区间来说左侧数据一定有序,因此只需要计算右侧区间导致左侧产生的逆序对累加即时逆序对总和

package main

import (
	"fmt"
)

func main() {

	var n int
	fmt.Scanf("%d", &n)

	q := make([]int, n)
	tmp := make([]int, n)

	for i := 0; i < n; i++ {
		fmt.Scanf("%d", &q[i])
	}

	//mergeSort(q, tmp, 0, n-1)
	fmt.Printf("%d\n", mergeSort(q, tmp, 0, n-1))

	//输出
	//for i := 0; i < n; i++ {
	//	fmt.Printf("%d ", q[i])
	//}
	//fmt.Println()
}

func mergeSort(q, tmp []int, l int, r int) int {

	if l >= r {
		return 0
	}

	mid := l + (r-l)>>1

	//mid := (l + r) >> 1
	//fmt.Printf("r : %d ", r>>1)

	res := mergeSort(q, tmp, l, mid) + mergeSort(q, tmp, mid+1, r)

	k := 0
	i := l
	j := mid + 1

	for i <= mid && j <= r {
		if q[i] <= q[j] {
			tmp[k] = q[i]
			k++
			i++
		} else {
			tmp[k] = q[j]
			k++
			j++
			res += mid - i + 1
		}
	}

	for i <= mid {
		tmp[k] = q[i]
		k++
		i++
	}

	for j <= r {
		tmp[k] = q[j]
		k++
		j++
	}

	for i, j = l, 0; i <= r; i, j = i+1, j+1 {
		q[i] = tmp[j]
	}

	return res
}
posted @ 2026-01-02 23:45  BlackSnow  阅读(8)  评论(0)    收藏  举报