计算可被给定查询k整除的数组中的整数数

时间:2017-09-24 08:27:05

标签: java arrays algorithm performance optimization

在这个问题中,我有一些查询,我必须在integers中输出array的计数,该计数可以被k整除(其中一个查询)。{{1}包含重复的元素。我正在尝试优化问题,我的方法如下:

代码:

array

上面的代码给出了正确的输出,但复杂度为public static void main(String[] args) { Scanner sc=new Scanner(System.in); int[] ar={2,4,6,9,11,34,654,23,32,54,76,21432,32543,435,43543,643,2646,4567,457654,75,754,7,567865,8765877,53,2}; int query=sc.nextInt(); int length=ar.length; int count=0; for (int i=0;i<query ;i++ ) { int x=sc.nextInt(); for (int j=0;j<length ;j++ ) { if(ar[j]>x){ if(ar[j]%x==0){ count++; } } } System.out.println("Count:"+count); } } ,如果数组大小要大得多,程序将O(query*length)

有人可以帮我优化问题吗?

3 个答案:

答案 0 :(得分:1)

您可以做的一个优化是利用short-circuiting,并使用一个if语句(而不是两个)。

所以改变这个:

if(ar[j]>x) {
  if(ar[j]%x==0) {

到此:

if(ar[j]>x && ar[j]%x==0) {

这不会影响算法的时间复杂度,但会有助Branch Prediction

答案 1 :(得分:1)

  

并且数组中元素的最大值为10 ^ 5

这使得它变得微不足道。使用boolean[10001]并标记所有查询的所有倍数。然后用它来测试元素。

新问题是如何在有许多小查询时标记所有倍数。最糟糕的情况是像{1, 1, 1, ...}这样的查询,但重复项可以轻微删除,例如,使用HashSet。现在最糟糕的情况是{1, 2, 3, 4, ...},需要10001/1 + 10001/2 + 10001/3...个步骤。您可以对最小的查询进行一些特殊处理,例如删除倍数。

例如,当您查看最多10个查询并删除它们之间的倍数时,最坏的情况是{2, 3, 5, 7, 11, 12, 13, 14...},这会使标记非常快。可能根本不需要这一步。

答案 2 :(得分:0)

您可以执行预计算步骤来构建除数表。对于数组中的每个元素,计算其除数。您可以在O(sqrt(V))中有效地计算数字的除数,假设V是数组中的最大值。构建完整的表将花费O(n * sqrt(V)),根据您的约束等于100,000 * sqrt(100,000) =~ 32M这不应该是很多。内存复杂性将是相同的。

然后,您可以通过表格中的查询在O(1)中回答您的问题。

您可以查看此link,了解如何在O(sqrt(V))中生成除数。