算法 - 归并排序 - 小和问题 | 逆序对问题

小和问题

在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和称为小和问题。

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 过程中,两部分数据有序的特征,使得大大加快比较的速度。

posted @ 2019-11-18 14:47  学习趁早  阅读(801)  评论(0编辑  收藏  举报