在数组中找到零中两个元素的最大总和

时间:2011-12-15 07:13:55

标签: algorithm

给定一个数组,找到该数组中距离零最远的两个元素之和的最具时间和空间效率的算法是什么?

修改 例如,[1,-1,3,6,-10]的最大总和等于-11,等于(-1)+( - 10)。

4 个答案:

答案 0 :(得分:2)

使用锦标赛比较方法查找最大和第二大元素使用最少的比较,总共n+log(n)-2。这样做两次,一次找到最大和第二大元素,比如ZY,然后再找到最小和最小的元素,比如说AB 。然后答案是Z+Y-A-B,因此再一次比较可以解决问题。总的来说,这需要2n+2log(n)-3次比较。这仍然是O(n),但实际上比扫描整个列表4次更快以找到A,B,Y,Z(总共使用4n-5比较)。

这两个教程中的图片和示例代码很好地解释了锦标赛方法:onetwo

答案 1 :(得分:1)

如果您的意思是绝对值最大的总和,则它是最大总和或最小总和。最大的总和是两个最大元素的总和。最小的总和是两个最小元素的总和。

所以你需要找到四个值:Maximal,second maximal,minimal,second minimal。你可以在O(n)时间和O(1)内存中一次完成。我怀疑这个问题可能是关于最小化O(n)中的常数 - 你可以通过取五个元素,排序每五个(可以在7个比较中完成)并将两个顶部元素与current-max元素进行比较来实现(最差时为3次比较)和带有当前最小元素的两个底部元素(同上。)这给出了每个元素的2.6次比较,这比明显算法的每个元素的3次比较有了很小的改进。

然后只需将两个最大元素相加,将两个最小元素相加,并取两个具有较大abs()的值。

答案 2 :(得分:0)

迭代遍历数组,跟踪到目前为止遇到的最小和最大元素。这是时间O(n),空间O(1),显然你不能做得更好。

int GetAnswer(int[] arr){
    int min = arr[0];
    int max = arr[0];
    int maxDistSum = 0;

    for (int i = 1; i < arr.Length; ++i)
    {
        int x = arr[i];
        if(Math.Abs(maxDistSum) < Math.Abs(max+x)) maxDistSum = max+x;
        if(Math.Abs(maxDistSum) < Math.Abs(min+x)) maxDistSum = min+x;

        if(x < min) min = x;
        if(x > max) max = x;
    }

    return maxDistSum;
}

关键的观察是最远的距离要么是两个最小元素的总和,要么是两个最大元素之和。

答案 3 :(得分:0)

让我们从一般的角度来看问题:

在数组中找到k整数的最大总和。

  • 首先跟踪FIRST k个整数 - 按照你的方式对它们进行排序。
  • 迭代数组,针对目前为止保存的整数的最小值测试每个整数。
    • 如果它大于保存的整数的最小值,请将其替换为最小值,并将其冒泡到正确的排序位置。

完成数组后,你得到最大的k个整数。

现在,您可以轻松将其应用于k=2