
"在混沌想法中,最不可理喻念头。"
1、长度最小的子数组
(1) 题目解析 
(2) 算法原理 
cpp
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
int sum = 0;
int len = INT_MAX;
for(int left=0,right=0;right<n;++right)
{
// 1.入窗口
sum += nums[right];
// 2.判断
while(sum >= target)
{
// 3.更新结果
len = min(len,right-left+1);
// 4.出窗口
sum -= nums[left++];
}
}
return len == INT_MAX ? 0:len;
}
};
2、无重复字符的最长子串
(1) 题目解析 
(2) 算法原理

cpp
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.size();
int hashtable[128] = {0};
int len = 0;
for(int left=0,right=0;right<n;++right)
{
//1.入窗口:进入哈希表
hashtable[s[right]]++;
// 2.判断:出现重复字符
while(hashtable[s[right]] > 1)
// 3.出窗口:过滤冲突字符
hashtable[s[left++]]--;
// 4.更新长度
len = max(len,right-left+1);
}
return len;
}
};
3、最大连续1的个数Ⅲ
(1) 题目解析 
(2) 算法原理

cpp
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int n = nums.size();
int max_num = 0;
for(int left=0,right=0,count=0;right<n;++right)
{
// 1.入窗口 对0做特殊处理
if(nums[right] == 0) count++;
// 2.判断:0的个数多了
while(count > k){
// 3. 出窗口:让left指向第一个遇到0位置的下一个
if(nums[left++] == 0) count--;
}
// 4.更新结果
max_num = max(max_num,right - left + 1);
}
return max_num;
}
};
4、 将 x 减到0的最小操作数
(1) 题目解析 
(2) 算法原理 
cpp
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int n = nums.size();
int sum = 0;
for(auto& e:nums) sum+=e;
int tar = sum - x;
if(tar < 0) return -1;
int tmp = 0;
int op_num = -1;
for(int left=0,right=0;right<n;++right)
{
// 1.入窗口
tmp += nums[right];
// 2.判断
while(tmp > tar)
// 4.出窗口
tmp -= nums[left++];
// 3.结果更新
if(tmp == tar) op_num = max(op_num,right-left+1);
}
if(op_num == -1) return -1;
else return n - op_num;
}
};
5、水果成篮
(1) 题目解析 
(2) 算法原理 
cpp
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int n = fruits.size();
unordered_map<int,int> hash;
int ret = 0;
for(int left=0,right=0;right<n;++right)
{
// 1.入窗口
int in = fruits[right];
hash[in]++;
// 2.判断
while(hash.size() > 2)
{
// 4.出窗口
int out = fruits[left];
hash[out]--;
// 移除
if(hash[out] == 0) hash.erase(out);
left++;
}
// 3.更新结果
ret = max(ret,right-left+1);
}
return ret;
}
};
优化: 
cpp
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int hashtable[100001] = {0};
int n = fruits.size();
int ret = 0;
// kinds:记录[left,right]种类数
for(int left=0,right=0,kinds=0;right<n;++right)
{
// 1.入窗口 && 维护kinds
if(hashtable[fruits[right]] == 0) kinds++;
hashtable[fruits[right]]++;
// 2.判断
while(kinds > 2)
{
// 4.出窗口
hashtable[fruits[left]]--;
// 移除
if(hashtable[fruits[left]] == 0) kinds--;
left++;
}
// 3.更新结果
ret = max(ret,right-left+1);
}
return ret;
}
};
6、找到字符串中所有字母异位词
(1) 题目解析

(2) 算法原理
cpp
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> res;
int hash1[26] = {0};
for(auto& ch:p) hash1[ch-'a']++;
int hash2[26] = {0};
int m = p.size();
for(int left=0,right=0,count=0;right<s.size();++right)
{
char in = s[right];
if(++hash2[in-'a'] <= hash1[in-'a']) count++;
if(right-left+1>m)
{
char out = s[left++];
if(hash2[out-'a']-- <= hash1[out-'a']) count--;
}
if(count == m) res.push_back(left);
}
return res;
}
};
7、串联所有单词的子串
(1) 题目解析 
进行这样的转换,这道题难道不像上一题的异位词?所以,我们是采用上一题的实现这一题的解法。
(2) 算法原理 
cpp
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
int n = s.size();
int len = words[0].size(); // 步长
int m = words.size(); // 长度
unordered_map<string,int> hash1;
for(auto& str:words) hash1[str]++;
vector<int> res;
for(int i=0;i<len;++i)
{
// 维护单词滑动窗口
unordered_map<string,int> hash2;
// right+len 处理边界问题
for(int left=i,right=i,count=0;right + len <= n;right+=len)
{
// 1.入窗口:向后移动len
string in = s.substr(right,len);
hash2[in]++;
if(hash1.count(in) && hash1[in] >= hash2[in]) count++; //有效字符
// 2.判断
if(right - left + 1 > len * m) //
{
// 3.出窗口
string out = s.substr(left,len);
if(hash1.count(out) && hash1[out] >= hash2[out]) count--;
hash2[out]--;
left += len;
}
if(count == m) res.push_back(left);
}
}
return res;
}
};
8、最小覆盖子串
(1) 题目解析

(2) 算法原理
cpp
class Solution {
public:
string minWindow(string s, string t) {
int hash1[128] = {0};
int kinds = 0;
for(auto& ch:t) if(hash1[ch]++ == 0) kinds++;
int hash2[128] = {0};
int begin=-1,minlen=INT_MAX;
// count用来记录[left,right]有效字符
for(int left=0,right=0,count=0;right<s.size();++right)
{
// 1.入窗口 && count维护
char in = s[right];
// 滤过多余字符
if(hash1[in] == ++hash2[in]) count++;
// 2.结果更新
while(count == kinds)
{
if(minlen > right - left + 1 ){
begin = left;
minlen = right - left + 1;
}
char out = s[left++];
// 滤过多余字符
if(hash1[out] == hash2[out]--) count--;
}
}
if(begin == -1) return "";
else return s.substr(begin,minlen);
}
};
本篇到此结束,感谢你的阅读。
祝你好运,向阳而生~
