编程语言
首页 > 编程语言> > java – 执行所有M操作所产生的数组中的最大元素

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