我尝试的以下算法将具有最初用于对数组进行排序的算法的顺序。例如,如果初始数组使用二叉树排序,则最佳情况为 O(n),平均情况为 O(n log n)。
算法要点:
数组已排序。存储排序后的值和相应的旧索引。从相应的旧索引创建二叉搜索树,用于确定它可以向前和向后走多远而不会遇到小于当前值的值,这将导致最大可能的子数组.
我会在问题[1, 5, 3, 5, 4, 1]中用数组说明方法
1 5 3 5 4 1
-------------------------
array indices => 0 1 2 3 4 5
-------------------------
此数组已排序。按升序存储值及其索引,如下所示
1 1 3 4 5 5
-------------------------
original array indices => 0 5 2 4 1 3
(referred as old_index) -------------------------
同时引用值及其旧索引很重要;像一个关联数组;
需要明确的几个术语:
old_index 指的是一个元素对应的原始索引(即原始数组中的索引);
例如,对于元素 4,old_index 为 4; current_index 为 3;
然而,current_index 指的是排序数组中元素的索引;
current_array_value 指的是排序后的数组中的当前元素值。
pre 指顺序前驱; succ指的是顺序后继
另外,最小值和最大值可以直接从排序后的数组的第一个和最后一个元素中得到,分别是min_value和max_value;
现在,算法如下,应该在排序数组上执行。
算法:
从最左边的元素开始。
对于排序数组左侧的每个元素,应用此算法
if(element == min_value){
max_sum = element * array_length;
if(max_sum > current_max)
current_max = max_sum;
push current index into the BST;
}else if(element == max_value){
//here current index is the index in the sorted array
max_sum = element * (array_length - current_index);
if(max_sum > current_max)
current_max = max_sum;
push current index into the BST;
}else {
//pseudo code steps to determine maximum possible sub array with the current element
//pre is inorder predecessor and succ is inorder successor
get the inorder predecessor and successor from the BST;
if(pre == NULL){
max_sum = succ * current_array_value;
if(max_sum > current_max)
current_max = max_sum;
}else if (succ == NULL){
max_sum = (array_length - pre) - 1) * current_array_value;
if(max_sum > current_max)
current_sum = max_sum;
}else {
//find the maximum possible sub array streak from the values
max_sum = [((succ - old_index) - 1) + ((old_index - pre) - 1) + 1] * current_array_value;
if(max_sum > current_max)
current_max = max_sum;
}
}
例如,
原始数组是
1 5 3 5 4 1
-------------------------
array indices => 0 1 2 3 4 5
-------------------------
排序后的数组是
1 1 3 4 5 5
-------------------------
original array indices => 0 5 2 4 1 3
(referred as old_index) -------------------------
在第一个元素之后:
max_sum = 6 [会减少到 1*6]
0
第二个元素之后:
max_sum = 6 [会减少到 1*6]
0
\
5
第三个元素之后:
0
\
5
/
2
中序遍历结果:0 2 5
应用算法,
max_sum = [((succ - old_index) - 1) + ((old_index - pre) - 1) + 1] * current_array_value;
max_sum = [((5-2)-1) + ((2-0)-1) + 1] * 3
= 12
current_max = 12 [最大可能值]
第四个元素之后:
0
\
5
/
2
\
4
中序遍历结果:0 2 4 5
应用算法,
max_sum = 8 [小于12被丢弃]
第五个元素之后:
max_sum = 10 [减少到2 * 5,因为小于8而丢弃]
在最后一个元素之后:
max_sum = 5 [减少到1 * 5,小于8就丢弃]
此算法将具有最初用于对数组进行排序的算法的顺序。例如,如果初始数组使用二进制排序,则最佳情况为 O(n),平均情况为 O(n log n)。
空间复杂度将为 O(3n) [O(n + n + n),n 用于排序值,另一个 n 用于旧索引,另一个 n 用于构造 BST]。但是,我不确定这一点。感谢您对算法的任何反馈。