我有一个算法问题,其中从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只存储在一个数组中并应用了操作,然后找到了最小值和最大值。
有没有更好的方法?
答案 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这个地方很好。
- 但如果列表中包含许多元素并且您不想运行那么多操作,那么最好检查操作的每个结果(如果是新的最大/最小值)并在必要时进行更新。