自己学习有个很不好的习惯,不怎么看书,只知道看题,看题又不会,各种查题解,今天把刘汝佳第八章前面讲的几个算法看了一下,加上各种百度,刚开始并不懂他们讲的,看了很久大致弄懂了逆序对问题的解决策略,下面是我自己对于这两种方法的理解。
方法1:归并排序。关于归并排序的原理,按照分治法的三个步骤,可以拆解为划分、递归、合并三个步骤,假设给出一个序列,如果要利用归并排序使其有序,那么就是先将该序列递归至最底层,即单个数,然后向上合并,借助一段辅助空间,将左右两个有序子序列合并成一个有序长序列。在这个合并的过程中,若存在左侧元素a[p]>右侧元素a[q],应将a[q]放入长序列的下一位置,此时,左侧序列中a[p]之后的每个元素均比a[q]大(子序列已经有序),而左侧元素在原始序列中的位置一定在右侧序列元素之前,因此,对于元素a[q],其逆序对个数便是m-p,统计所有逆序对的个数之和即可求得序列中所有逆序对个数。
方法2:树状数组。对于树状数组求逆序对个数,大部分都需要离散化处理,毕竟一个数组中的元素不可能一定处于1....n的范围内,因此,先把原数组排序,将数组元素值与排序后的位置一一对应,并记录元素的初始位置m,然后利用一个同等大小的a数组,初始化为0,在插入元素i时,将a[i]置为1,利用树状数组快速求区间和的特性,统计a[0]...a[i-1]的和sum,sum是小于当前元素的数的总个数,m是元素的初始位置,即该元素之前共有m个数(0...m-1),在这m个数中有sum个时小于该元素的,那么大于该元素的元素个数即为m-sum,也就是所要求的逆序对的个数,最后统计所有逆序对个数即可。