当前位置: 代码迷 >> java >> 计算所有连续子阵列中存在的最大元素
  详细解决方案

计算所有连续子阵列中存在的最大元素

热度:48   发布时间:2023-07-26 14:21:46.0

由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);

}

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

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

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

Bruteforce方法(获取所有间隔并计算每个间隔的最大值)将在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) (先前的最大和当前元素)。 因此,您计算a0的值,然后计算a1的值,依此类推O(n^2) 您可以存储它们,然后以您想要的格式输出它们。 你最后得到了O(n^2)空间和时间的超级简单算法。

PS注意到你不能及时做到比O(n^2)更好,因为你需要至少输出n*(n+1)/2元素,所以你只能希望减少空间复杂度。

  相关解决方案