【问题标题】:Counting maximum element present in all continuous subarrays计算所有连续子数组中存在的最大元素
【发布时间】:2015-08-07 21:03:31
【问题描述】:

由 N 个正整数组成的数组 A。数组 A 有 N × (N+1) / 2 非空连续子数组。

我们必须计算所有连续子数组中存在的最大元素。
例如:

1 2 3 
Subarray List :
[1]
[2]
[3]
[1,2]
[2,3]
[1,2,3]

Maximum Element :
[1]
[2]
[3]
[2]
[3]
[3]

我的方法:
使用Segment Tree查询区间中存在的最大元素

代码:

public static void get_max_freq(int a , int b , ArrayList<Long> freq ,ArrayList<Integer> P , int n , int[] A){

      if(a>b) return;

    int index = query(1,0,n, a, b, A);  // Segment Tree O(Logn)

    long temp = (index-a+1)*(b-index+1);
    freq.add(temp);
    P.add(A[index));

    get_max_freq(a,index-1, freq, P, n, A);
    get_max_freq(index+1, b, freq, P,n, A);

}

如果元素在数组中不是唯一的,我想知道我的解决方案是否正确。

有没有比这更快更好的解决方案。

【问题讨论】:

  • 如果您的代码有效,但您正在寻求改进,您应该在codereview.stackexchange.com 上提问这个问题,而不是 SO。
  • 在回答之前知道这是来自在线竞赛!

标签: java algorithm data-structures


【解决方案1】:

我认为你过于复杂了。要构建分段树,您将需要O(nlogn) 空间,您将在O(n) 时间内完成此操作。在此之后,您将需要回答您的 n(n+1)/2 查询,每个查询都需要 O(logn),所以基本上您将花费您 O(n^2*logn)

蛮力方法(获取所有间隔并计算每个间隔的最大值)将在 O(n) 内存和 O(n^3) 中运行。

但是您可以使用以下简单算法计算所有最大值。让您的数组为[a0, a1, a2, ..., an]。从第 0 个元素开始并计算从该元素开始的范围内的所有最大值:max(a0-a0), max(a0-a1), ... max(a0-an)。您可以在O(n) 中执行此操作,因为max(ai-an) = max( max(ai-a(n-1)), an)(前一个最大值和当前元素)。所以你在O(n^2) 中计算a0 的值,然后是a1 等等。您可以存储它们,然后以您想要的格式输出它们。通过一个超级简单的算法,你最终得到了O(n^2) 空间和时间。

P.S.注意你不能及时比O(n^2)做得更好,因为你至少需要输出n*(n+1)/2元素,所以你只能寄希望于降低空间复杂度。

【讨论】:

  • O(n^2) 将不起作用,因为 N 是 10^6 而我的方法是 O(nlogn)A 是大小为 N 的原始数组而不是 N*(N+1)/2
  • @SunnyPathak 你的方法到底如何nlogn?您需要回答n^2 查询,每个查询都是logn。在我看来完全不像nlogn
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 2017-07-21
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 2014-01-06
相关资源
最近更新 更多