LeetCode 面试题 17.18. 最短超串

文章描述了在一个较长数组中找到包含较小子数组所有元素的最短子数组的问题,通过滑动窗口算法解决,强调了时间复杂度为O(B)和空间复杂度为O(S)。
摘要由CSDN通过智能技术生成

面试题 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]

输出: []

提示:

  • big.length <= 100000
  • 1 <= small.length <= 100000

提示 1

从蛮力解法开始。


提示 2

一种蛮力解决方案是对于每个起始位置不断向前移动,直到你找到一个包含所有目标字符的子序列为止。


提示 3

另一种对蛮力方法的考虑是,我们取每个起始索引,在目标字符串中寻找每个元素的下一个出现位置。所有这些出现位置的最大值标志着子序列的尾部(该子序列包含所有目标字符)。这个算法的时间复杂度是多少?怎样才能使它更快呢?


提示 4

考虑一下前面解释的蛮力解法。瓶颈在于我们反复查询某个特定字符的下一个出现位置。有办法优化该过程么?你应该能在O(1)时间内完成。


提示 5

你能从每个索引中预先计算一个特定字符的出现位置吗?尝试使用一个多维数组。


提示 6

在得到了预计算的解法之后,考虑一下如何降低空间复杂度。你应该能够将其降低到O(SB)的时间和O(B)的空间(其中B是较大数组的大小,S是较小数组的大小)。


提示 7

另一种考虑方法是:假设你有一个每个元素所在索引的列表。你能找到包含所有元素的第一个子序列吗?你能找到第二个吗?


提示 8

考虑使用堆。

解法:滑动窗口

class Solution {
    public int[] shortestSeq(int[] big, int[] small) {
        int[] ans = new int[2];
        ans[1] = Integer.MAX_VALUE;
        int n = big.length;
        int m = small.length;
        Map<Integer, Integer> need = new HashMap<>();
        Map<Integer, Integer> window = new HashMap<>();
        for (int i = 0; i < m; i++) {
            need.put(small[i], 1);
        }
        int left = 0;
        int right = 0;
        while (right < n) {
            if (need.containsKey(big[right])) {
                window.merge(big[right], 1, Integer::sum);
            }
            while (window.size() == m) {
                if (right - left < ans[1] - ans[0]) {
                    ans[0] = left;
                    ans[1] = right;
                }
                if (need.containsKey(big[left])) {
                    if (window.merge(big[left], -1, Integer::sum) == 0) {
                        window.remove(big[left]);
                    }
                }
                left++;
            }
            right++;
        }
        return ans[1] == Integer.MAX_VALUE ? new int[0] : ans;
    }
}

复杂度分析

  • 时间复杂度:O(B),B是较大数组的大小。
  • 空间复杂度:O(S),S是较小数组的大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值