我真的会动之滑动窗口
最近在整理之前刷过的********题目,想写写一些常见的、典型的解题技巧或者方法。于是我想介绍一下滑动窗口方法。
1.无重复字符的最长子串
/*给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 */
#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n=s.size();
int right=-1,ans=0;
unordered_set<char> dp;
for(int i=0;i<n;++i)
{
if(i!=0)
{
dp.erase(s[i-1]);
}
while(right+1<n&&!dp.count(s[right+1]))
{
dp.insert(s[right+1]);
++right;
}
ans=max(ans,right-i+1);
}
return ans;
}
};
int main() {
string s;
cin >> s;
Solution so1;
int ans = so1.lengthOfLongestSubstring(s);
cout << ans << endl;
return 0;
}
2.最小覆盖子串
/*给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"*/
#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;
class Solution {
public:
string minWindow(string s, string t) {
if (t.size() == 0 || s.size() == 0) return "";
unordered_map<char, int> m_t;
unordered_map<char, int> window;
for (int i = 0; i < t.size(); i++) m_t[t[i]]++;
int left = 0, right = 0;
int start = 0, minlen = INT_MAX;
int match = 0;
while (right < s.size()) {
char c1 = s[right];
if (m_t.count(c1)) {
window[c1]++;
if (window[c1] == m_t[c1]) {
match++;
}
}
right++;
while (match == m_t.size()) {
char c2 = s[left];
if (right - left < minlen) {
start = left;
minlen = right - left;
}
if (m_t.count(c2)) {
window[c2]--;
if (window[c2] < m_t[c2]) {
match--;
}
}
left++;
}
}
return minlen == INT_MAX ? "" : s.substr(start, minlen);
}
};
int main() {
string s, t;
cin >> s >> t;
Solution so1;
string ans = so1.minWindow(s, t);
cout << ans << endl;
return 0;
}
3.找到字符串中所有字母异位词
/*给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。
示例 1:
输入:
s: "cbaebabacd" p: "abc"
输出:
[0, 6]*/
#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ans;
if (s.size() == 0) return ans;
unordered_map<char, int> m_p;
unordered_map<char, int> window;
int left = 0, right = 0;
int match = 0;
for (int i = 0; i < p.size(); i++) m_p[p[i]]++;
while (right < s.size()) {
char c1 = s[right];
if (m_p.count(c1)) {
window[c1]++;
if (window[c1] == m_p[c1]) {
match++;
}
}
right++;
while (match == m_p.size()) {
char c2 = s[left];
if (right - left == p.size()) {
ans.push_back(left);
}
if (m_p.count(c2)) {
window[c2]--;
if (window[c2] < m_p[c2]) {
match--;
}
}
left++;
}
}
return ans;
}
};
int main() {
string s, p;
cin >> s >> p;
Solution so1;
vector<int> ans = so1.findAnagrams(s, p);
for (int i = 0; i < ans.size(); i++) {
printf("%d ", ans[i]);
}
printf("\n");
return 0;
}
下面的这个地址有十分详细的解答过程,我就不献丑了。 le地址
Leetcode刷题整合 文章被收录于专栏
都是作者刷到的一些感觉是好题整理到一起的,辛苦整理不易,麻烦给个赞,有疑问请留言