可以使用动态规划算法找到最大和。扫描数组并将每个元素的值添加到有效的最大子序列和(子序列以不大于该元素的值结束)。
有效的实施需要某种方法来快速找到给定子范围内的最大值。可以使用增强二叉搜索树来做到这一点。芬威克树只是增强二叉搜索树的有效实现。芬威克树最常见的用途是查找某个子范围内的值之和。简单的修改允许使用它来查找子范围最大值(这是有效的,因为在这种特殊情况下,芬威克树中的值永远不会减少)。
有关详细信息,请参阅此 Python 代码:
array = [1, 4, 4, 2, 2, 3, 3, 1]
numbers = sorted(set(array))
n = len(numbers)
indexes = {numbers[v]:v+1 for v in range(0, n)}
n += 1
bit = [0] * n
result = 0
for x in array:
pos = indexes[x]
i = pos
maximum = 0
while i != 0:
maximum = max(maximum, bit[i])
i = i & (i-1)
x += maximum
i = pos
while i < n:
bit[i] = max(bit[i], x)
i += i & -i
result = max(result, x)
print(result)
indexes
字典用于将芬威克树的大小从输入数组中的最大数字减小到数组的大小。第一个嵌套while
查找 Fenwick 树中的子范围最大值。第二次嵌套while
更新其中一项总和后更新 Fenwick 树。
此代码仅适用于正数数组。一般情况下,应通过过滤掉所有非正数来对输入数组进行预处理。
时间复杂度为 O(N log N)。空间复杂度为 O(N)。