C++程序 在两个数组中找到k对最小元素之和
给定两个升序排列的整数数组arr1[]和arr2[],以及一个整数k。找到k对最小和的元素,使得一对元素属于arr1[],另一对元素属于arr2[]
例如:
方法1(简单)
- 找到所有的对并存储它们的和。此步骤的时间复杂度为O(n1*n2),其中n1和n2是输入数组的大小。
- 然后按总和对对进行排序。此步骤的时间复杂度为O(n1n2 * log (n1n2))
总时间复杂度: O(n1n2 * log (n1n2))
方法2(有效):
我们从最小的配对开始一次找到k个最小的和。其思想是跟踪已经针对每个元素arr1 [i1]考虑的arr2 []的所有元素,以便在迭代中我们只考虑下一个元素。为此,我们使用一个索引数组index2 []来跟踪另一个数组中的下一个元素的索引。它仅意味着在每个迭代中,第一个数组中的哪个元素应与第二个数组的元素相加。我们在每个迭代中增加索引数组中的值以形成下一个最小值对。
输出
时间复杂度: O(k*n1),其中n1表示给定数组的大小。
辅助空间: O(n1),其中n1表示给定数组的大小。
方法3: 使用排序,最小堆,映射
不要通过所有可能的和组合来进行蛮力搜索,应该找到一种方式来限制我们的搜索空间以寻找可能的候选和组合。
- 对数组A和数组B进行排序。
- 创建一个min heap,即在C++中使用priority_queue将和组合以及组成和的数组A和B的索引存储在其中。堆的顺序由和确定。
- 使用最小可能的和组合,即(A [0] + B [0])和来自两个数组的元素的索引(0,0)初始化堆。堆中的元组将是(A [0] + B [0],0,0)。堆的顺序由第一个值即两个元素的和确定。
- 弹出堆以获取当前最小的和以及构成和的元素的索引。让元组为(sum,i,j)。
- 接下来将(A [i + 1] + B [j],i + 1,j)和(A [i] + B [j + 1],i,j + 1)插入min heap中,但确保索引对,即(i +1,j)和(i,j +1)在min heap中不存在。在C++中可以使用set来检查这一点。
- 回到第4步,重复K次。
输出
时间复杂度: O(n*logn),其中k<=n。
辅助空间: O(n),n为给定数组的大小。