【问题标题】:How can I make this Algorithm more efficient?我怎样才能使这个算法更有效?
【发布时间】:2016-11-10 19:45:21
【问题描述】:

我有一个算法,它产生一个包含所有可能值之和的二维数组。例如,对于数组 [1,5,8,4,5],二维数组 sums[1][3] 应返回原始数组 (17) 中索引 1-3 的总和。我相信就大O而言,效率是O(N2)。有什么办法可以让这个算法更有效率吗?

public static int[][] sum(int[] values){
    int[][] sums = new int[values.length][values.length];
    for(int x = 0; x < values.length; x++){
        int total = 0;
        for(int y = x; y < values.length; y++) {
            total += values[y];
            sums[x][y] = total;
        }
    }
    return sums;
}

【问题讨论】:

  • 您需要填写一个大小为N^2 的表格。你怎么能在不到O(N^2) 的时间内做到这一点??
  • 类似的问题。可以在 O(nlog(n)) 中完成。 stackoverflow.com/a/37907843/3160529
  • 这正是我想知道的。这是我演讲幻灯片中的一个问题,我一直在努力理解它。

标签: algorithm data-structures time-complexity big-o


【解决方案1】:

你可以在O(n)时空用前缀和数组解决这个问题:

array    = [1, 5, 8, 4, 5]
prefixes = [1, 6,14,18,23]

sums(1,3) = prefixes[3] - prefixes[0] = 18 - 1 = 17

【讨论】:

  • 这绝不是回答问题。 sums(1, 3) = array[1] + array[3]。那么有什么意义呢?你已经用减法代替了加法。而且它没有填充二维数组。
  • @EugeneSh。感谢您的评论。 array[1] + array[3] 不等于 9 吗?我认为 OP 的意思是 sums[1][3] 应该返回 array[1] + array[2] + array[3] 的总和,即 5 + 8 + 4 = 17。据我了解,问题是“我怎样才能让这个算法更有效?”我认为我的回答建议了一种方法。
  • 您的答案有效,但这不是我需要的。我正在寻找的是一种生成 2 数组的算法,这样arr[1][3] 将返回索引 1-3 中所有值的总和。这个答案使用一种方法来计算总和(尽管这很可能是不可能的)。
  • @TopCat 你讲课幻灯片上的问题措辞是什么?
  • @TopCat 用这种措辞,我认为 O(n) 建议回答了这个问题,但当然,如果没有更多上下文,很难确定。
【解决方案2】:

按以下方式计算prefix总和:

public static int[] sum(int[] values){
    int[] prefix_sums = new int[values.length];
    prefix_sums[0] = values[0];
    for(int x = 1; x < values.length; x++){
        prefix_sums[x] = prefix_sums[x-1] + values[x];
    }
    return prefix_sums;
}

根据您的查询,您希望找到从索引 x 到索引 y 的总和(基于 0 的索引),这是获得总和的方法:

if(x==0)
    result = prefix_sums[y];
else
    result = prefix_sums[y] - prefix_sums[x-1];

希望对你有帮助!!!

【讨论】:

    猜你喜欢
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    相关资源
    最近更新 更多