找到具有不同数字的最大连续子阵列和

时间:2014-10-09 18:34:55

标签: algorithm arrays

在给定的数组中找到具有不同数字的最大连续子数组和。如果在任何子数组中至少有两个相等的数字,则该数字的值等于0。

所有数字都是正数。

我写了O(n²)暴力算法,但它肯定太慢了。 我尝试使用Kadane的算法混合它,但它似乎不起作用。

1 个答案:

答案 0 :(得分:1)

使用分段树可以获得O(n log n)时间复杂度。

  1. 我们假设答案的左边框(让我们称之为L)是固定的。它可以忽略左边的所有内容。数组其余部分的每个元素都可以表示为:
    a)+x如果它是x的第一次出现 b)-x如果它是x的第二次出现 c)0如果是x的第三次(或更晚),则为x = a[i] 其中[L, R]
    那么答案是R >= L所有子阵列[0, n - 1]的最大子阵列总和。

  2. 那么如何才能有效实施呢?最初,为L范围构建分段树。段树中的每个叶子都包含以0开头并以此叶子结束的前缀和(L = 0到目前为止)。填写+x(通过遍历整个数组并将-xO(n log n)添加到段树中的相应足够的内容)。这些部分适用于L。还有一个观察结果:当a[L]递增时,该值仅在最多3个位置发生变化(因为数字O(log n)的第一次出现现在处于另一个位置,但对于其他数字,没有任何变化) 。段树中的每次更新都是O(log n),因此需要L时间才能递增O(n log n)一次。总时间复杂度为L,因为O(n)递增L次。不要忘记查询段树以获得每个{{1}}的最大值,并选择最大值作为答案。

  3. 所以你需要的是一个支持两个操作的分段树:为给定范围内的所有元素添加相同的数字,并在所有元素中获得最大值。这是一个众所周知的问题,并不是很难实现。