在一系列数字的加法和减法之后找到最小值和最大值

时间:2012-08-06 16:24:16

标签: c++ algorithm

我有一个算法问题,其中从1到N给出了数字,并且要执行许多操作,然后必须在它们之间找到最小/最大值。

两个操作 - 加法和减法

并且操作的形式为b c d,其中a是要执行的操作,b是起始编号,c是结束编号,d是要添加/减去的编号

例如

  

假设数字是1到N.   和   N = 5

1 2 3 4 5

我们执行

操作

1 2 4 5

2 1 3 4

1 4 5 6

通过这些操作,我们将从1到N的数字为

1 7 8 9 5

-3 3 4 9 5

-3 3 4 15 11

因此最大值为15,最小值为-3

我的方法: 我已经取了数字的下限和上限,在这种情况下它是1和5只存储在一个数组中并应用了操作,然后找到了最小值和最大值。

有没有更好的方法?

2 个答案:

答案 0 :(得分:2)

我将假设所有更新(加/减)操作都在找到最大/最小值之前发生。我没有一个很好的解决方案,可以将更新和最小/最大操作混合在一起。

您可以使用普通数组,其中数组索引i处的值是原始数组的索引i和索引(i-1)之间的差值。这使得从数组的索引0到索引i的和为原始数组的索引i的值。

减法是加数和否定数,因此可以类似地对它们进行处理。当我们需要将k从索引i添加到原始数组到索引j时,我们将k添加到数组的索引i,并将k减去我们数组的索引(j + 1)。每次更新需要O(1)次。

通过累加值并记录最大/最小值,可以找到原始数组的最小值/最大值。每次操作需要O(n)次。我假设这对整个阵列都做了一次。

伪代码:

a[N] // Original array
d[N] // Difference array

// Initialization
d[0] = a[0]
for (i = 1 to N-1)
    d[i] = a[i] - a[i - 1]

// Addition (subtraction is similar)
add(from_idx, to_idx, amount) {
    d[from_idx] += amount
    d[to_idx + 1] -= amount
}

// Find max/min for the WHOLE array after add/subtract
current = max = min = d[0];
for (i = 1 to N - 1) {
   current += d[i]; // Sum from d[0] to d[i] is a[i]
   max = MAX(max, current);
   min = MIN(min, current);
}

答案 1 :(得分:1)

通常,在性能观点上找不到最佳/最大值没有“最佳方式”,因为它取决于该应用程序的使用方式。

- 在列表中查找max和min需要O(n)时间,所以如果你想运行很多(在输入的上下文中很多)操作,你的方法是在所有操作之后找到min / max这个地方很好。

- 但如果列表中包含许多元素并且您不想运行那么多操作,那么最好检查操作的每个结果(如果是新的最大/最小值)并在必要时进行更新。