查找元素数量最大差异的子数组

时间:2016-12-11 17:31:48

标签: arrays algorithm recursion max array-difference

我在尝试解决以下算法问题时遇到了困难。
给定一个数组A [1 ... N],其中每个A [i]是X或Y.找到一个连续的子阵列A [i..j],其中X和Y之间的绝对差值最大。
例如,在数组A = [X,X,Y,Y,X,Y,Y,X,Y,X]中,最大绝对差值是子阵列A [3 .. 7],因为我们有3 Y和1 X(数组A的索引从1开始)。
另一个例子,如果我们的数组A = [X,X,Y,X,X,Y,Y,X],则最大绝对差值是子阵列A [1 .. 5]。
给出一个简单的算法来解决这个问题。分析算法的运行时间。

以下是我创建的算法:

MAX-DIF-SUBARRAY(A, n)
dif_now = 0
dif_new = 0
left = 0    # the lowest index
right = 0   # the highest index
for i=2 to n
   for j=1 to n+1-i
      Xcount, Ycount = 0
      for k=j to j+i-1
         if A[k] = X
            Xcount = Xcount + 1
         else Ycount = Ycount + 1
      dif_new = |Xcount - Ycount|
      if dif_new > dif_now
         dif_now = dif_new
         left = k
         right = j+i-1
return dif_now, left, right. 

该算法需要时间O(n ^ 3)。
有谁能帮我找到一个可以在O(n ^ 2)运行的更好的算法?另外,如何制作这种算法的递归版本?
先感谢您。

1 个答案:

答案 0 :(得分:1)

您可以在线性时间内执行此操作,方法是遍历数组一次,并保留一个在遇到X时增加的总和,并在遇到Y时减少。同时这样做也可以跟踪此总和达到的值最小值和最大值。

这给你两个指数。这两个中的最小值加1是子数组的开始,另一个索引标记该子数组中的最后一个元素。最大化的差异是在上述过程中记录的最小值和最大值之间的差异。

伪代码:

MAX-DIF-SUBARRAY(A):
    n = size(A)
    count = 0
    min_count = 0
    max_count = 0 
    left = 1
    right = 1

    for i=1 to n:
        if A[i] == X:
            count = count + 1
        else
            count = count - 1
        if count > max_count:
            max_count = count
            left = i
        if count < min_count:
            min_count = count
            right = i
    dif = max_count - min_count
    if left > right: # swap the two indices
        temp = left
        left = right
        right = temp
    left = left + 1
    return dif, left, right