算法 - 归并排序 - 小和问题 | 逆序对问题
小和问题
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和称为小和问题。
input: [2,4,5,1,7,3]
2 左侧比 2 小的数,没有;
4 左侧比 4 小的数,2;
5 左侧比 5 小的数,2,4;
1 左侧比 1 小的数,没有;
7 左侧比 7 小的数,2,4,5,1;
3 左侧比 3 小的数,2,1。
output: 2+2+4+2+4+5+1+2+1=23
此处使用归并排序,在 merge 时,由于左右两部分都已经有序,可以确定一侧的数都大于正在比较的数,例如:
归并 2 4 5 | 1 3 7 两个部分时,2 比 3 小,此时可以确定后面的数都大于 2,此时便可以一次性计算小和 2 * 2(两个数大于 2),而不用一个个遍历。
总结
使用归并排序算法的快速之处在于,归并的两个部分对内都是有序的,如 2 4 5 | 1 3 7
两个部分。因此在比较大小的时候,可以迅速确定整批的数据大小,而不用重复遍历计算。
又由于每一次 merge 的数据都是新的,此前没有重复算过,因此不会多次计算或漏算。
逆序对问题
在一个数组中,左边的数如果比右边的数大,则这两个数构成一个逆序对。
这个问题也适合使用归并排序的方法进行批量计算,例如
仍然以 2 4 5 | 1 3 7 数据举例,因为
2 4 5 | 1 3 7
↑ ↑
此时 (2,1) 组成逆序对,因此 (4,1) (5,1) 逆序对也可以直接推导出来
使用这种计算有效的利用了归并排序 merge 过程中,两部分数据有序的特征,使得大大加快比较的速度。