给定未排序的数组,找到数组中两个元素之间的最大减法

时间:2014-12-07 10:59:37

标签: arrays max maximize

我在微软采访中得到了这个问题:给定一个未排序的数组,找到数组中两个元素之间的最大减法是这样的:

(Index1, Index2) = arr[Index2] - arr[Index1].    Index1<Index2.

示例:

given the array: [1, 5, 3, 2, 7, 9, 4, 3] -> Output: (1,9)=8.
given the array: [4, 9, 2, 3, 6, 3, 8, 1] -> Output: (2,8)=6.

天真的解决方案在O(n ^ 2)次上工作:用所有其他索引扫描第一个减法索引并保存最大值,继续下一个索引,依此类推。

有没有办法优化这个?

2 个答案:

答案 0 :(得分:3)

写下来时非常简单。重新解决问题,您希望找到每个元素右侧的最大元素。现在给出第一个例子,这是:

[1, 5, 3, 2, 7, 9, 4, 3]
=>
[9, 9, 9, 9, 9, 4, 3]

现在,请注意,maximums数组只是右边的累积最大值。有了这个属性,很容易构造O(n)时间算法。

在python中实现:

def find_max(xs):
    ys = []
    cur_max = float('-inf')
    for x in reversed(xs):
        cur_max = max(x, cur_max)
        ys.append(cur_max)
    ys = ys[::-1][1:]
    return max(y - x for x, y in zip(xs, ys))

我们也可以懒惰地构造最大数组,这样做会给我们O(1)内存,这是最好的:

def find_max(xs):
    cur_max = float('-inf')
    cum_max = xs[-1]
    for i in range(len(xs) - 2, -1, -1):
        cur_max = max(cur_max, cum_max - xs[i])
        cum_max = max(cum_max, xs[i])
    return cur_max

答案 1 :(得分:1)

我认为这是正确的并且O(nlogn):在中间分割并从右边选择最大值,从左边开始选择最小值。另外两个季度分开,如果其中一个给出更大的结果继续递归该分支。

第二个例子:

4, 9, 2, 3| 6, 3, 8, 1 -> 2 and 8
4, 9| 2, 3, 6, 3, 8, 1 -> 4 and 8
4, 9, 2, 3, 6, 3| 8, 1 -> 2 and 8

所以正在进行正确的分裂:

4, 9, 2, 3, 6, 3, 8| 1 -> 2 and 1

选择28选项。它也适用于第一个例子。