java – 执行所有M操作所产生的数组中的最大元素
作者:互联网
对于初始化为0的N个元素的数组,我们给出了一系列M个操作的排序(p; q; r).操作(p; q; r)表示应将整数r加到所有数组元素A [p]; A [p 1]; :::; A [q].您将输出执行所有M操作所产生的数组中的最大元素.有一个天真的解决方案,只需执行所有操作,然后返回最大值,需要O(MN)时间.我们正在寻找更有效的算法.
我正在寻找动态编程解决方案.你们有什么想法吗?
解决方法:
这可以用O(M N)求解,如下所述.首先,为您的操作建模如下:
class Operation {
final int p;
final int q;
final int r;
Operation(int p, int q, int r) {
this.p = p;
this.q = q;
this.r = r;
}
}
然后,创建一个数组,在op.r位置添加op.r,在位置op.q 1添加-op.r包含上限(或op.q用于独占上限).这是M上的循环:
int[] array = new int[10];
Operation[] ops = {
new Operation(1, 7, 2),
new Operation(2, 5, 3),
new Operation(1, 3, 1)
};
for (Operation op : ops) {
int lo = op.p;
int hi = op.q + 1;
if (lo >= 0)
array[lo] = array[lo] + op.r;
if (hi < array.length)
array[hi] = array[hi] - op.r;
}
最后,运行大小为N的数组,并通过累计每个先前注册的/ – op.r值来找到最大值
int maxIndex = Integer.MIN_VALUE;
int maxR = Integer.MIN_VALUE;
int r = 0;
for (int i = 0; i < array.length; i++) {
r = r + array[i];
System.out.println(i + ":" + r);
if (r > maxR) {
maxIndex = i;
maxR = r;
}
}
System.out.println("---");
System.out.println(maxIndex + ":" + maxR);
我的例子产生:
0:0
1:3
2:6
3:6
4:5
5:5
6:2
7:2
8:0
9:0
---
2:6
Java 8并行版
如果您有大量内核,则可以使用Java 8 API并行化以前的算法:
// Finally a use-case for this weird new Java 8 function!
Arrays.parallelPrefix(array, Integer::sum);
System.out.println(Arrays.stream(array).parallel().max());
对于非常大量的N和足够数量的内核,这可能比先前的顺序解决方案更快.
标签:java,algorithm,arrays,dynamic-programming 来源: https://codeday.me/bug/20190608/1201091.html