查找整数是否为整数之和的有效方法

时间:2012-04-28 19:55:25

标签: java arrays optimization

这是一项学校作业,但是,要求是该程序“以最大的性能实施” - 这与我的口味含糊不清,因为我不知道记忆力是否超过速度等等。但是,我是什么我正在寻找是否通过对输入数据进行一些智能操作来解决问题的“棘手”方法。

所以,这就是问题所在:考虑你有两个数组,A和B,写一个函数,如果B中有这样的整数,则返回1,等于任意两个后续元素的总和A。

以下是我的写作。请注意,我没有使用Hashmap<Integer>,因为我认为加速所需的内存是一个足够强大的缺点,以O(n * m)速度作为我的最坏情况而不是O(n)。< / p>

public static int arrayContainsSum(int[] a, int[] b)
{
    int offsetA = a.length - 1;
    int offsetB = offsetA;
    int index = b.length - 1;
    int result = 0;
    int tested;

    while (index >= 0)
    {
        if (offsetA > 0) a[offsetA] += a[--offsetA];
        else if (offsetA == 0) // This has a danger of overflowing the int
            a[offsetA--] = multiply(a);
        tested = b[index];
        if ((offsetA < 0 && tested != 0 && a[0] % tested != 0) ||
            offsetB == 0)
        {
            // No point to test this element as it doesn't 
            //divide the product of sums
            offsetB = a.length - 1;
            index--;
        }
        if (tested == a[offsetB--])
        {
            result = 1;
            break;
        }
    }
    return result;
}

private static int multiply(int[] input)
{
    int accumulator = input.length > 0 ? 1 : 0;
    for (int i : input)
        if (i != 0) accumulator *= i;
    return accumulator;
}

有一些我不关心的事情:整数溢出(可能由于乘法而发生)。我假设array.length与从局部变量读取一样快。

但是,再一次,我的问题是“是不是可以分析地解决这个问题?”这意味着更高的效率?

PS。问题没有提到数组是否只包含唯一成员 - 没有限制。我还认为可以通过排序a来优化(如果我检测到这种情况),以便在b[x]小于a或更大的最小元素的情况下, a中的最大元素,它可以节省一些查找 - 但是,这又会增加复杂性,可能并不完全合理。

3 个答案:

答案 0 :(得分:1)

public static int arrayContainsSum(int[] a, int[] b) {
  final Set<Integer> sums = new HashSet<Integer>();
  for (int i = 0; i < a.length - 1; i++) sums.add(a[i] + a[i+1]);
  for (int x : b) if (sums.contains(x)) return 1;
  return 0;
}

答案 1 :(得分:0)

速度无关紧要,除非你有超过一百万个元素,它需要超过1秒。顺便说一句,你不想制作超过一百万个元素的数组。

多达7的Java版本甚至不包含基本的集合操作,这并不幸运。但是,您可以在Google Guava库中找到它们(该代码已经过适当的测试并且尽可能高效)。

假设您有2套20个元素ab - 可以从1到100和200中随机选择。

a = RandomInteger[{100}, 20]
b = RandomInteger[{200}, 20]

之后,您想要找到a后续元素总和的哪些元素与b

相交
ap = Table[Total[{a[[i]], a[[i + 1]]}], {i, 1, Length[a] - 1}]
Intersection[ap, b]

例如:

{73,43,99,33,80,35,54,82,50,23,92,22,54,4,14,14,8,80,92,85}
{121,139,158,158,51,176,65,84,76,172,73,148,71,128,55,134,4,32,183,134}
{116,142,132,113,115,89,136,132,73,115,114,76,58,18,28,22,88,172,177}
{73,76,172}

答案 2 :(得分:0)

如有疑问,请使用蛮力。

嗯 - 当然,如果任务是编写高性能解决方案,这可能还不够,但在优化解决方案之前,您需要一个解决方案。

val a = List (3, 9, 7, 4, 16)    
val b = List (29, 12, 21, 16, 18, 14) 

for (i <- (0 to a.length - 2); 
  j = i+1;
  if b.exists (_ == a(i)+a(j))) yield (a(i), a(j), a(i)+a(j)) 

它多久运行一次? 外部循环从1运行到array-length-1(这是一个列表)以生成i,j只是后续元素。

但对于b,它始终贯穿整个数组,

如果按值排序b,则可以在b中进行二进制查找。 我想规则中不允许使用HashMap,因为你有两个Arrays。否则HashMap会更快。