数组中给定数字的最小窗口

时间:2010-08-01 16:26:26

标签: algorithm arrays window

最近看到这个问题:

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

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

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

尽管范围1到4也包含A的元素,但返回的范围是3到5,因为它的长度小于前一个范围((5 - 3)<(4 - 1))

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

为问题提供有效的解决方案。在此先感谢

1 个答案:

答案 0 :(得分:3)

迭代列表的简单解决方案。

  1. 有一个左右指针,最初都是零
  2. 向前移动右指针,直到[L..R]包含所有元素(如果右边到达末尾,则退出)。
  3. 向前移动左指针,直到[L..R]不包含所有元素。查看[L-1..R]是否短于当前最佳值。
  4. 这显然是线性时间。您只需要跟踪子阵列中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
        }
    }