Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何从两个排序数组的对中获得K个最小乘积?_Algorithm - Fatal编程技术网

Algorithm 如何从两个排序数组的对中获得K个最小乘积?

Algorithm 如何从两个排序数组的对中获得K个最小乘积?,algorithm,Algorithm,给出了两个排序数组。我们必须从这些数组的对中找到K个最小乘积。我可以想到一个mnlogk解决方案,但是即使数组不是按排序的,这个解决方案也可以工作。我们能利用这个排序顺序找到更好的解决方案吗 我尝试使用大小为k的最大堆来获得mnlogk解决方案 输入:nums1=[-2,-1,0,1,2],nums2=[-3,-1,2,4,5],k=3 输出:[-10,-8,-6] 说明:-2*5、-2*4、2*-3不要使用堆,而是尝试按排序顺序生成产品 想象一个n*m网格,由索引形成到相应的数组中。在任何给定

给出了两个排序数组。我们必须从这些数组的对中找到K个最小乘积。我可以想到一个mnlogk解决方案,但是即使数组不是按排序的,这个解决方案也可以工作。我们能利用这个排序顺序找到更好的解决方案吗

我尝试使用大小为k的最大堆来获得mnlogk解决方案

输入:nums1=[-2,-1,0,1,2],nums2=[-3,-1,2,4,5],k=3 输出:[-10,-8,-6]
说明:-2*5、-2*4、2*-3

不要使用堆,而是尝试按排序顺序生成产品

想象一个
n*m
网格,由索引形成到相应的数组中。在任何给定的时间点,网格被划分为“已检查”和“尚未检查”部分。我们将保持一个不变量,即每对被检验的产品小于未被检验产品的产品。难点在于证明它们之间的边界有
O(n+m)
对;数组被排序这一事实对于证明是至关重要的

现在,您可以沿着边界测试产品,获取最小值,并相应地修改边界。此操作将花费
O(n+m)
时间,并将执行
k次。总体复杂性是O(k(n+m)


最后的优化:上面的计划一次又一次地重新计算边界沿线的许多产品。将边界表示为排序映射可能会将复杂性降低到O(klog(n+m))

这里有一个具有O(kmin(n,m))时间复杂性的算法

设A和B为整数列表排序,即A=[a1 a2 a3…am]带ai≤ ai+1,B=[b1 b2 b3…bn]和bi≤ bi+1

现在假设ai≥ 0和bi≥ 0下面我们将演示如何计算负整数

设p=(i j)是一对,其中i和j是ai和bj的索引。设P是一个对的列表。集合P=[(11)(12)(13)…(1n)]。假设k>0(和k≤ m x n)。设R是k个第一乘积对的列表。初始化R=[]

  • 将p的第一对p=(i j)与R相加

  • 如果R的大小为k,则终止

  • 设置p=(i+1 j)。而p的乘积大于乘积 对于P中的下一对q,交换P和q

  • 转到步骤1

  • 上述算法的时间复杂度为O(kn),仅适用于包含非负整数的A和B。注意,如果m 下面是一个例子,用A=[2 6 13]和B=[1 6 9]来说明算法。下面的矩阵显示了每个(i j)的乘积ai x bj

    这是计算开始时p和R的初始状态。我们在P中的每一对(ij)后面加上乘积ai x bj的值

    在第一次迭代中,
    (1 1):2
    被添加到R中,p中的第一对成为
    (1+1)

    在下一次迭代中,
    (21):6
    被添加到R中,p中的第一对成为
    (2+11)
    。因为该对的乘积大于P中下一对的乘积,所以它们被交换

    R = [(1 1):2 (2 1):6]
    P = [(3 1):13 (1 2):12 (1 3):18] 
    P = [(1 2):12 (3 1):13 (1 3):18]
    
    下一次迭代,类似于上一次迭代的操作

    R = [(1 1):2 (2 1):6 (1 2):12]
    P = [(2 2):36 (3 1):13 (1 3):18]
    P = [(3 1):13 (1 3):18 (2 2):36] 
    
    在这个迭代中,将
    (3 1):13
    添加到R之后,第一对p变为
    (3+1)
    ,但该对不存在。所以,它只是从P中删除

    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13]
    P = [(1 3):18 (2 2):36]
    
    以下是p为空之前的所有剩余迭代

    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18]
    P = [(2 3):54 (2 2):36]  
    P = [(2 2):36 (2 3):54]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36]
    P = [(3 2):78 (2 3):54]  
    P = [(2 3):54 (3 2):78]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54]
    P = [(3 3):117 (3 2):78] 
    P = [(3 2):78 (3 3):117]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54 (3 2):78]
    P = [(3 3):117]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54 (3 2):78 (3 3):117]
    P = []
    
    现在,如果A和B同时包含非负整数和负整数,我们可以使用上述算法同时求解最多4个子问题,以获得k个最小整数。为此,我们定义了迭代器函数F(A,B),该函数在每次调用时使用上述算法按递增顺序生成下一个乘积。设A-和A+是A的子列表,分别包含其负整数和非负整数。B-和B+也是这样。我们为以下4个子问题调用迭代器函数

    F(A+, B+)
    F(A+, reverse(B-))
    F(reverse(A-), B+)
    F(reverse(A-), reverse(B-))  
    

    其中,reverse(L)返回列表L及其元素的顺序相反。我们迭代这四个迭代器,选择k个最小的返回对

    你能给出一个例子来说明这个问题吗?在你的例子中,你把第一个数组中的-2与第二个数组中的5和4配对。这是正确的吗?@Robert yes,这是解决这个问题的正确方法。(我很惊讶没有从两套产品中找到K个最大的产品,答案是否恰当。)4个子问题的识别就在现场。在循序渐进地介绍要遵循的程序时,我看不出我≠P中的1,而n开始时是B的基数,在过程中用作P中的下一对n。@greybeard捕捉得好!我修正了打字错误。谢谢我添加了一个详细的示例。@greybeard参见示例,第三次迭代,删除
    (12):12
    @greybeard
    (1+1)=(21)
    ,第一对的乘积变为
    (22):36
    。我不确定你的意思。获取最小边界值会有什么帮助?我们不是每次都要取k最小值吗?我们如何修改边界?
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13]
    P = [(1 3):18 (2 2):36]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18]
    P = [(2 3):54 (2 2):36]  
    P = [(2 2):36 (2 3):54]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36]
    P = [(3 2):78 (2 3):54]  
    P = [(2 3):54 (3 2):78]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54]
    P = [(3 3):117 (3 2):78] 
    P = [(3 2):78 (3 3):117]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54 (3 2):78]
    P = [(3 3):117]
    
    R = [(1 1):2 (2 1):6 (1 2):12 (3 1):13 (1 3):18 (2 2):36 (2 3):54 (3 2):78 (3 3):117]
    P = []
    
    F(A+, B+)
    F(A+, reverse(B-))
    F(reverse(A-), B+)
    F(reverse(A-), reverse(B-))