我在尝试解决以下算法问题时遇到了困难。
给定一个数组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)运行的更好的算法?另外,如何制作这种算法的递归版本?
先感谢您。
答案 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