大家好,我是周一。
在上一篇归并排序中,我们讲了归并排序的基本概念、merge(合并)过程等,今天趁热打铁,我们来说说使用归并排序的一些常见面试题。
一、小和问题
1、题目描述:
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个给定数组的小和。
2、例子:
数组为:[1,3,4,2,5]
1左边比1小的数:没有
3左边比3小的数:1
4左边比4小的数:1,3
2左边比2小的数:1
5左边比5小的数:1,3,4,2
所以小和为1+(1+3)+1+(1+3+4+2)=16
3、思路:
找每一个数右边比当前数大的个数,(个数 * 当前数) 的累加和就是结果。
这咋和归并排序联系上的呢,仔细想想,在左组和右组merge的时候,会比较数的大小,这时就可以在右组找到比左组当前数大的个数。
4、详细的参考代码:
1 | java复制代码/** |
二、逆序对问题
1、题目描述:
设有一个数组 [a1, a2, a3,… an],对于数组中任意两个元素ai,aj,若i<j,ai>aj,则说明ai和aj是一对逆序对。求一个给定数组的逆序对个数。
2、例子:
3 5 2 1 0 4 9
所有逆序对是:(3,2),(3,1),(3,0),(5,2),(5,1),(5,0),(5,4),(2,1),(2,0),(1,0)。逆序对个数为10。
3、思路:
合并的时候,从右往左合并,(此时右组位置 - mid位置) 的累加和 即是逆序对个数。
这又咋和归并排序联系上的呢,仔细想想,在左组和右组merge的时候,会比较数的大小,但是我要找到的是右边更小的,所以可以采用从右往左合并的方式;同时在处理相等的时候,需要先拷贝右组的,这样才能准确找出右组小的个数。
4、详细的参考代码:
1 | java复制代码/** |
OK,今天就暂时先说利用归并排序解决小和和逆序对问题的题目。
有时候,各种排序算法掌握它本身并不难,难的是你能够充分理解它的过程和精髓,更难的是在真正遇到实际题目的时候,能够想到用这种排序算法来解决它。所以,算法无捷径,唯有多练习,在有足够多的量,积累量变,然后才能迎来质变,那时才能信手拈来,加油。
本文转载自: 掘金