【发布时间】:2019-05-31 22:28:15
【问题描述】:
我有一个数字数组,例如:
A = [1, 5, 2, 4, 3]
还有一个决定排名的数组,例如:
B = [0, 2, 1]
我的目标是找到 A 的所有“服从”等级 B 的子数组。如果子数组服从等级,这意味着子数组的第 i 个最小元素必须以 B[i] 作为其(子数组)指数。所以要匹配一个子数组,其中最小的元素必须在位置 0,第二小的元素必须在位置 2,最大的元素必须在位置 1。
所以比如这里,有两个匹配排序的A的子数组:[1,5,2](因为A[0]
到目前为止,我已经设法找到了一个具有O(mn)(m 是 len(A),n 是 len(B))时间复杂度的解决方案,它遍历所有长度为 3 的子数组并验证是否它们的顺序正确:
A = [1, 5, 2, 4, 3]
B = [0, 2, 1]
m = len(A)
n = len(B)
for i in range(m - n + 1):
current_subarray = A[i:i + n]
# we now do n - 1 comparaisons to check whether the subarray is correctly ordered.
for B_index in range(n - 1):
if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
break
else:
print("Subarray found:", current_subarray)
结果:
Subarray found: [1, 5, 2]
Subarray found: [2, 4, 3]
这可行,但我想知道是否有更好的优化算法(比O(mn) 更好)来完成这项任务。
【问题讨论】:
-
您是否正在寻找时间复杂度较低的东西?因为我不确定这样的事情是否存在。
-
@ParitoshSingh 是的,这就是我要找的。也许不是,但我想这就是我问的原因:)。让我怀疑的是我正在处理子数组,其中一些子数组重叠 - 也许有一种方法可以通过缓存一些来减少计算量,比如优化字符串搜索(如 KMP)算法的工作原理?跨度>
-
我看到的问题是这个。考虑 [0,1,3,2]。在第一个子列表中,[1,3] 的相对等级为 1 和 2,而在第二个子列表中,[1,3] 的相对等级为 0 和 2。本质上,结果取决于“窗口” ,因此您需要重新评估才能确定。在这种情况下,您可能缓存的任何结果最终都需要重新检查,从而失去所有好处。 (如果我错了,请有人纠正我)
-
@ParitoshSingh 正确,但是考虑长度 > 2 的子数组。例如,当我从 [0, 1, 3] 转到 [1, 3, 2] 时(在您的列表中) ,假设我对第一个子数组进行了比较并推断它不服从。我继续第二个子数组,但是我可能已经做了一些比较(最后两个元素成为第二个子数组的前两个元素)。即使,正如您所说,知道 1
-
确实如此,但是因为它的“一些”案例而不是全部案例,所以无论如何您都必须重新检查所有案例。而且由于比较是一个恒定的时间操作,因此您最终会出现在第 1 格。更改窗口会改变有关比较有利和不利的所有内容。