给定两个数组A[n]
和B[m]
,如何找到包含B
中所有元素的A
中最小的窗口。
我尝试在O(n)时间内解决这个问题,但是我遇到了麻烦。是否有任何众所周知的算法或过程来解决它。
给定两个数组A[n]
和B[m]
,如何找到包含B
中所有元素的A
中最小的窗口。
我尝试在O(n)时间内解决这个问题,但是我遇到了麻烦。是否有任何众所周知的算法或过程来解决它。
m > n
,则A
不能包含B
的所有元素(因此我们有一个O(1)
的解决方案)。B
的元素映射到序列 {0..m-1}(这是O(n)
,因为m <= n
)。C[m]
来计算当前窗口中B
成员的出现次数(初始化为0)。创建一个变量z
来计算C
中0元素的数量(初始化为m
)。
创建变量s
和e
来表示当前窗口的开始和结束
e < n
时:
z
不为零,则增加e
并更新C
和z
。O(1)
s
并更新C
和z
。O(1)
可以证明while循环的迭代次数不超过2n
。因此整个过程是O(n)
,我想。
计数。如果窗口不能被缩小,则称其为“最小化”。即,在增加其左边框或减小其右边框后,它不再是有效的窗口(不包含来自B的所有元素)。在您的示例中有三个:[0,2],[2,6],[6,7]。
假设您已经找到了最左边的最小窗口[left,right]。(在您的示例中为[0,2])现在我们只需将其向右滑动即可。
// count[x] tells how many times number 'x'
// happens between 'left' and 'right' in 'A'
while (right < N - 1) {
// move right border by 1
++right;
if (A[right] is in B) {
++count[A[right]];
}
// check if we can move left border now
while (count[A[left]] > 1) {
--count[A[left]];
++left;
}
// check if current window is optimal
if (right - left + 1 < currentMin) {
currentMin = right - left + 1;
}
}
count
的工作方式,而我的代码更难理解。 - Artelius