在给定的数组中找到具有不同数字的最大连续子数组和。如果在任何子数组中至少有两个相等的数字,则该数字的值等于0。
所有数字都是正数。
我写了O(n²)暴力算法,但它肯定太慢了。 我尝试使用Kadane的算法混合它,但它似乎不起作用。
答案 0 :(得分:1)
使用分段树可以获得O(n log n)
时间复杂度。
我们假设答案的左边框(让我们称之为L
)是固定的。它可以忽略左边的所有内容。数组其余部分的每个元素都可以表示为:
a)+x
如果它是x
的第一次出现
b)-x
如果它是x
的第二次出现
c)0
如果是x
的第三次(或更晚),则为x = a[i]
其中[L, R]
。
那么答案是R >= L
所有子阵列[0, n - 1]
的最大子阵列总和。
那么如何才能有效实施呢?最初,为L
范围构建分段树。段树中的每个叶子都包含以0
开头并以此叶子结束的前缀和(L = 0
到目前为止)。填写+x
(通过遍历整个数组并将-x
或O(n log n)
添加到段树中的相应足够的内容)。这些部分适用于L
。还有一个观察结果:当a[L]
递增时,该值仅在最多3个位置发生变化(因为数字O(log n)
的第一次出现现在处于另一个位置,但对于其他数字,没有任何变化) 。段树中的每次更新都是O(log n)
,因此需要L
时间才能递增O(n log n)
一次。总时间复杂度为L
,因为O(n)
递增L
次。不要忘记查询段树以获得每个{{1}}的最大值,并选择最大值作为答案。
所以你需要的是一个支持两个操作的分段树:为给定范围内的所有元素添加相同的数字,并在所有元素中获得最大值。这是一个众所周知的问题,并不是很难实现。