问题描述
由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);
}
我想知道如果元素在数组中不是唯一的,那么我的解决方案是正确的。
有没有比这更快更好的解决方案。
1楼
我认为你过于复杂了。
要构建一个分段树,你需要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
元素,所以你只能希望减少空间复杂度。