题目
假设你有两个数组,一个长一个短,短的元素均不相同。找到长数组中包含短数组所有的元素的最短子数组,其出现顺序无关紧要。
返回最短子数组的左端点和右端点,如有多个满足条件的子数组,返回左端点最小的一个。若不存在,返回空数组。
示例
输入:
big = [7,5,9,0,2,1,3,5,7,9,1,1,5,8,8,9,7]
small = [1,5,9]
输出: [7,10]
输入:
big = [1,2,3]
small = [4]
输出: []
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-supersequence-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法1:滑动窗口
Java实现
class Solution {
public int[] shortestSeq(int[] big, int[] small) {
int n = big.length;
int l = 0, r = 0;
Map<Integer, Integer> need = new HashMap<>();
Map<Integer, Integer> window = new HashMap<>();
//填充need窗口
for (int i = 0; i < small.length; i++) {
need.put(small[i], 1);
}
int valid = 0;
int minlen = Integer.MAX_VALUE;
int[] res = new int[2];
boolean var = false;
while (r < n) {
int flag = big[r];
r++;
if (need.containsKey(flag)) {
window.put(flag, window.getOrDefault(flag, 0) + 1);
if (window.get(flag) == need.get(flag)) valid++;
}
//当window窗口都有need中的字符时,开始收缩
while (valid == need.size()) {
//更新最短超串
if (r - l < minlen) {
minlen = r - l;
res[0] = l;
res[1] = r - 1;
var = true;
}
//开始收缩
int out = big[l];
l++;
if (need.containsKey(out)) {
if (window.get(out) == need.get(out)) valid--;
window.put(out, window.get(out) - 1);
}
}
}
if (var) return res;
else return new int[]{};
}
}