【问题标题】:Minimum Window for the given numbers in an array数组中给定数字的最小窗口
【发布时间】:2010-08-01 16:26:26
【问题描述】:

最近看到这个问题:

给定 2 个数组,第二个数组包含第一个数组的一些元素,返回第一个数组中包含第二个数组所有元素的最小窗口。

例如: 给定 A={1,3,5,2,3,1} 和 B={1,3,2}

输出: 3 , 5(其中 3 和 5 是数组 A 中的索引)

虽然范围1到4也包含A的元素,但是返回范围3到5 因为它包含因为它的长度小于之前的范围( ( 5 - 3 )

我已经设计了一个解决方案,但我不确定它是否正常工作并且效率不高。

为问题提供有效的解决方案。提前致谢

【问题讨论】:

  • 这是作业吗?如果是这样,请相应地标记。
  • 不.. 这不是家庭作业.. 否则我会这样标记它!!
  • 我无法理解第三点3.将左指针向前移动,直到[L..R] 不包含所有元素。看看 [L-1..R] 是否比当前最佳值短。 假设我们找到了第一个窗口,现在我们想前进到下一个窗口,算法是如何工作的?

标签: algorithm arrays window


【解决方案1】:

遍历列表的简单解决方案。

  1. 有一个左右指针,最初都为零
  2. 向前移动右指针直到 [L..R] 包含所有元素(如果右到达末尾则退出)。
  3. 将左指针向前移动,直到 [L..R] 不包含所有元素。查看 [L-1..R] 是否比当前最佳值短。

这显然是线性时间。您只需要跟踪 B 的每个元素中有多少在子数组中,以检查子数组是否是潜在的解决方案。

该算法的伪代码。

size = bestL = A.length;
needed = B.length-1;
found = 0; left=0; right=0;
counts = {}; //counts is a map of (number, count)
for(i in B) counts.put(i, 0);

//Increase right bound
while(right < size) {
    if(!counts.contains(right)) continue;
    amt = count.get(right);
    count.set(right, amt+1);
    if(amt == 0) found++;
    if(found == needed) {
        while(found == needed) {
            //Increase left bound
            if(counts.contains(left)) {
                amt = count.get(left);
                count.set(left, amt-1);
                if(amt == 1) found--;
            }
            left++;
        }
        if(right - left + 2 >= bestL) continue;
        bestL = right - left + 2;
        bestRange = [left-1, right] //inclusive
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2012-12-29
    • 2019-07-31
    相关资源
    最近更新 更多