Arrays 查找数组的最大元素是另一个元素的除数

Arrays 查找数组的最大元素是另一个元素的除数,arrays,algorithm,Arrays,Algorithm,给定一个长度为N的非零整数数组。编写一个函数,返回数组的最大元素,该元素是同一数组中其他元素的除数。如果此数字不存在,则返回0。我知道如何在O(n^2)中求解。有可能做得更快吗?首先,请注意,您假设测试整数A是否除以整数B可以在O(1)中完成。我猜您也假设不允许进行预计算(如a栋) 因为(没有多项式算法是已知的)不是一个选项,所以不能比O(n^2)(最坏情况)更快 例如,给定输入{1112716139}(所有整数都是素数,每个整数的平方都小于下一个整数),您无法避免检查所有对。我这样做了 int

给定一个长度为N的非零整数数组。编写一个函数,返回数组的最大元素,该元素是同一数组中其他元素的除数。如果此数字不存在,则返回
0
。我知道如何在
O(n^2)
中求解。有可能做得更快吗?

首先,请注意,您假设测试整数A是否除以整数B可以在O(1)中完成。我猜您也假设不允许进行预计算(如a栋)

因为(没有多项式算法是已知的)不是一个选项,所以不能比O(n^2)(最坏情况)更快

例如,给定输入{1112716139}(所有整数都是素数,每个整数的平方都小于下一个整数),您无法避免检查所有对。

我这样做了

int f(int* a, int size)
{
    int max = 0;
    for (int i = 0; i < size; i++)
        for (int j = 0; j < size; j++)
            if (a[i] > a[j] && a[i] % a[j] == 0 && a[j] > max)
                max = a[j];
    return max;
}
intf(int*a,int-size)
{
int max=0;
对于(int i=0;ia[j]&&a[i]%a[j]==0&&a[j]>max)
max=a[j];
返回最大值;
}

我已经研究了您的问题一段时间,并找到了一种有时比暴力更好的解决方案

它基于以下理念:

  • 我们可以按照这样的顺序执行搜索:首先测试更大的除数候选项。这样,我们可以在找到除数后立即终止搜索

  • 测试某个候选
    divw
    是否是数字
    w
    的除数的一种方法是计算
    r=floor(w/divw)
    ,然后检查
    r*divw==w
    。有趣的是,当它失败时,我们可以将下一个候选除数
    w
    的上限计算为
    topw=floor(w/(r+1))
    。因此,我们可以丢弃
    divw
    topw
    之间的任何内容

第二点的示例:假设我们正在测试如果
divw=10
w=12
的除数,我们计算
r=floor(12/10)=1
,并且
topw=floor(w/2)=6
。因此,我们不需要检查
7
9
之间的集合中的数字是否是
12
的除数

为了实现这个算法,我使用了一个堆来保存集合中的数字,并使用下一个必须测试的除数候选作为密钥

所以

  • 初始化堆,将前一个元素作为其更大的潜在因子

  • 从堆中弹出第一个元素(
    w
    ),并检查潜在的除数候选(
    divw
    )是否实际上是一个除数

  • 如果是,则将其作为最大除数返回

  • w
    divw
    计算
    topw
    ;搜索集合
    divw'
    中等于或小于
    topw
    的下一个元素(使用二进制搜索);如果找到,请在队列中再次按
    w
    divw'

  • 除非队列为空,否则转到
    2

  • 公共Lisp中的一个实现是可用的

    我想计算这个算法的理论计算成本是很有挑战性的,特别是对于一般情况,所以我不打算这么做


    在运行了十几次之后,当N较高且数字分散(这意味着一个数字作为另一个数字的除数的概率较低)时,它似乎比蛮力方法表现得更好。另一方面,当N较低或数字密集分布在一个小范围内(这意味着一个数字成为另一个除数的概率较高)时,蛮力似乎更快。

    我无法准确理解这些要求。据我所知,
    0
    的结果最多可能出现在空输入中。对于非空输入,第一个元素本身将是一个除数,因此结果将是一个非空集合的最大值。@Codor问题要求数字是同一数组中其他元素的除数。我觉得要求很清楚。@Anonymous谢谢你的澄清,我误读了另一部分。如果两个元素相同,例如a[3]=a[11]=7,这算不算“其他元素的除数”?@Anton数组中最大的元素有多大?你的推理对于整数未绑定的理论情况是正确的。但是如果你认为它是一个实际的问题,其中整数被绑定(例如,32位整数),并且集中于平均情况而不是最坏的情况,那么它可能变成一个有趣的问题!