九章算法面试题9 前k大的和

九章算法官网-原文网址:

http://www.jiuzhang.com/problem/9/

题目

【初阶】有两个数组A和B,每个数组有k个数,从两个数组中各取一个数加起来可以组成k*k个和,求这些和中的前k大。

【进阶】有N个数组,每个数组有k个数,从N个数组中各取一个数加起来可以组成k^N个和,求这些和中的前k大。


解答

初阶:定义C[i][j] = A[i]+B[j],假设A,B从大到小排序,那么C[0][0]为最大的和。


将A和B的和变为一个矩阵,更容易思考。

将C[0][0]拿走以后,C[1][0]和C[0][1]则都可能成为第二个最大和。设定可能成为最大和的集合S,一开始S={C[0][0]},每次从集合中选一个最大的数C[i][j]出来,然后将C[i+1][j]和C[i][j+1]加入到集合中(如果有的话)。直到选足k个数。由于同时可能在集合中存在的元素只有n个(每行每列会同时有一个数在集合中),采用堆来实现该集合,每次找一个最大数复杂度O(logn),总时间复杂度O(nlogn)

进阶:先对前两个数组求前k大和,将结果与第三个数组求前k大和,然后第四个……直到第N个。


面试官角度

初阶问题的难度是需要将所有的和构造成一个矩阵的形式来思考。然后考察基本的数据结构堆的使用。 进阶问题中,考察的是如何将一个复杂的问题化简为一个我们已经知道解法的问题。我们可以解决2个数组求前k大和的问题了,那么N个数组的情况,就想办法变为2个数组的情况就可解了。


你可能感兴趣的:(九章算法面试题)