LeetCode面试题17.18 最短超串(典型滑动窗口)
Posted xdu-lakers
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode面试题17.18 最短超串(典型滑动窗口)相关的知识,希望对你有一定的参考价值。
题目链接
https://leetcode-cn.com/problems/shortest-supersequence-lcci/
题目描述
假设你有两个数组,一个长一个短,短的元素均不相同。找到长数组中包含短数组所有的元素的最短子数组,其出现顺序无关紧要。
返回最短子数组的左端点和右端点,如有多个满足条件的子数组,返回左端点最小的一个。若不存在,返回空数组。
示例 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.典型利用滑动窗口
定义滑动窗口为[left,right],当滑动窗口内的元素满足small数组,则把left与right的值都设置为从left下标开始第二次出现small数组中的元素的下标。例如big数组[1,2,3,5,7,6],small数组[1,3,5],当left = 0,right = 3时,滑动窗口满足small元素,则把left与right值设置为2。然后继续重复以上操作。自己想的滑动窗口最终因为超时没能AC,但是所有用例都通过了。
标准的滑动窗口:
1.把[left,right]称为一个窗口;
2.先右移右指针扩大窗口,直到窗口中的数字满足small数组要求;
3.满足要求时,停止增加right,转而增加left缩小窗口,直到不满足要求
4.重复2,3步直到right走到big尽头
滑动窗口的模板:
int left = 0, right = 0; //left right为双指针
while (right < s.size())
{
window.add(s[right]);
right++; //右移右指针扩大窗口
while (valid) //直到窗口中的数字满足small数组要求;
{
window.remove(s[left]); //满足要求时,停止增加right,转而增加left缩小窗口,直到不满足要求
left++;
}
}
AC代码
1 class Solution { 2 public: 3 vector<int> shortestSeq(vector<int>& big, vector<int>& small) { 4 vector<int> ans; 5 if(small.size()>big.size()) return ans; 6 map<int,int>b_mp; 7 map<int,int>s_mp; 8 for(int i = 0; i < small.size(); i++) s_mp[small[i]]++; 9 int count = 0; 10 int l = 0; 11 int r = 0; 12 int l_ans=-1; 13 int r_ans=-1; 14 int max = INT_MAX; 15 while(l <= r && r < big.size()) 16 { 17 if(s_mp[big[r]] == 0) //右指针右移,扩大窗口 18 { 19 r++; 20 continue; 21 } 22 else 23 { 24 b_mp[big[r]]++; 25 if(b_mp[big[r]] == 1) count++; 26 } 27 28 if(count == small.size()//valid条件) //整个if语句对应模板中 window.remove(s[left]);【开始缩小滑动窗口->对l的值进行处理】 29 { 30 while(l <= r) 31 { 32 if(b_mp[big[l]] == 0) l++; 33 else if(b_mp[big[l]] == 1) break; 34 else if(b_mp[big[l]] > 1) //本句代码是为了处理如下例子:big数组[1,2,1,3,5,7,6],small数组[1,3,5] 35 { 36 b_mp[big[l]]--; 37 l++; 38 } 39 } 40 int len = r - l; 41 if(len < max) //迭代更新len值 42 { 43 max = len; 44 l_ans = l; 45 r_ans = r; 46 } 47 } 48 r++; 49 } 50 if(max != INT_MAX) 51 { 52 ans.push_back(l_ans); 53 ans.push_back(r_ans); 54 } 55 56 return ans; 57 } 58 };
以上是关于LeetCode面试题17.18 最短超串(典型滑动窗口)的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode刷题100天—面试题 16.16. 部分排序(排序)—day58
Leetcode刷题100天—面试题 16.16. 部分排序(排序)—day58