最短超串(滑动窗口解法)

面试题 17.18. 最短超串

假设你有两个数组,一个长一个短,短的元素均不相同。找到长数组中包含短数组所有的元素的最短子数组,其出现顺序无关紧要。

返回最短子数组的左端点和右端点,如有多个满足条件的子数组,返回左端点最小的一个。若不存在,返回空数组。

示例 1:

输入:
big = [7,5,9,0,2,1,3,5,7,9,1,1,5,8,8,9,7]
small = [1,5,9]
输出: [7,10]
示例 2:

输入:
big = [1,2,3]
small = [4]
输出: []
代码如下:
class Solution {
    public int[] shortestSeq(int[] big, int[] small) {
        //左右双指针表示滑动窗口,start和min用来保存最优解
        int left = 0;
        int right = 0;
        int start = 0;
        int count = 0; //count用来保存匹配的个数
        int min = Integer.MAX_VALUE;
        HashMap<Integer,Integer> window = new HashMap<>();
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int x : small) {
            map.put(x,map.getOrDefault(x,0) +1);
        }
        //移动right扩大窗口
        while (right < big.length) {
            int a = big[right];
            if (map.containsKey(a)) {
                window.put(a,window.getOrDefault(a,0) +1);
                if (window.get(a) == map.get(a)) {
                    count++;
                }
            }
            right++;
            //直到满足的时候  要开始缩小左边
            while (count == map.size()) {
                //更新最小窗口
                if ((right - left) < min) {
                    start = left;
                    min = right -left;
                }

                int b = big[left];
                if (map.containsKey(b)) {
                    window.put(b,window.getOrDefault(b,0) -1);
                    if (window.get(b) < map.get(b)) {
                        count--;
                    }
                }
                left++;
            }
        }
        //判断min有没有发生改变,改变了说明有符合的情况,如果没有直接返回一个[]
        if (min == Integer.MAX_VALUE) {
            return new int[0];
        }
        return new int[]{start,min+start-1};
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值