Arrays 查找数组的最大元素是另一个元素的除数
给定一个长度为N的非零整数数组。编写一个函数,返回数组的最大元素,该元素是同一数组中其他元素的除数。如果此数字不存在,则返回Arrays 查找数组的最大元素是另一个元素的除数,arrays,algorithm,Arrays,Algorithm,给定一个长度为N的非零整数数组。编写一个函数,返回数组的最大元素,该元素是同一数组中其他元素的除数。如果此数字不存在,则返回0。我知道如何在O(n^2)中求解。有可能做得更快吗?首先,请注意,您假设测试整数A是否除以整数B可以在O(1)中完成。我猜您也假设不允许进行预计算(如a栋) 因为(没有多项式算法是已知的)不是一个选项,所以不能比O(n^2)(最坏情况)更快 例如,给定输入{1112716139}(所有整数都是素数,每个整数的平方都小于下一个整数),您无法避免检查所有对。我这样做了 int
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
在运行了十几次之后,当N较高且数字分散(这意味着一个数字作为另一个数字的除数的概率较低)时,它似乎比蛮力方法表现得更好。另一方面,当N较低或数字密集分布在一个小范围内(这意味着一个数字成为另一个除数的概率较高)时,蛮力似乎更快。我无法准确理解这些要求。据我所知,
0
的结果最多可能出现在空输入中。对于非空输入,第一个元素本身将是一个除数,因此结果将是一个非空集合的最大值。@Codor问题要求数字是同一数组中其他元素的除数。我觉得要求很清楚。@Anonymous谢谢你的澄清,我误读了另一部分。如果两个元素相同,例如a[3]=a[11]=7,这算不算“其他元素的除数”?@Anton数组中最大的元素有多大?你的推理对于整数未绑定的理论情况是正确的。但是如果你认为它是一个实际的问题,其中整数被绑定(例如,32位整数),并且集中于平均情况而不是最坏的情况,那么它可能变成一个有趣的问题!