借助双指针实现滑动窗口,虽然遇到新的题还是不会,但我还是要写,狠狠感动自己
(1)果 [ l , r ] [l , r] [l,r]存在重复子串,那么 [ l , r , r + 1 , r + 2..... ] [l, r, r + 1, r + 2.....] [l,r,r+1,r+2.....]也存在重复子串;
(2)如果 [ l , r ] [l, r] [l,r]不存在重复子串,那么 [ l , l + 1 , l + 2 , . . . , r ] [l, l + 1, l+ 2, ..., r] [l,l+1,l+2,...,r]也不存在重复子串。
那么由此就可以构造滑动窗口啦!
while (l < r && mp[s[r]] > 1) {
mp[s[l]]--;
l ++;
}
这部分代码是说,我们考虑(1)情况,对于新进窗口的 r 来说,如果右边加上他,导致存在重复子串,那么我们就需要处理窗口左边的字符,也就是把 l++ ;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ans = 0;
map<char, int> mp;
for (int l = 0, r = 0; r < s.size(); r ++) {
mp[s[r]] ++;
while (l < r && mp[s[r]] > 1) {
mp[s[l]]--;
l ++;
}
ans = max(ans, r - l + 1);
}
return ans;
}
};
直接套模板(不是)
(1)果 [ l , r ] [l , r] [l,r]的元素和大于target
,那么 [ l , r , r + 1 , r + 2..... ] [l, r, r + 1, r + 2.....] [l,r,r+1,r+2.....]的元素的和必定大于target
;
(2)如果 [ l , r ] [l, r] [l,r]的元素和小于target
,那么 [ l , l + 1 , l + 2 , . . . , r ] [l, l + 1, l+ 2, ..., r] [l,l+1,l+2,...,r]的元素和也必定小于target
。
所以只需要去长度最小的 ans 即可
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0, ans = 1e9;
for (int l = 0, r = 0; r < nums.size(); r++) {
sum += nums[r];
while (l <= r && sum >= target) {
ans = min(ans, r - l + 1);
sum -= nums[l];
l++;
}
}
if (ans != 1e9)
return ans;
else
return 0;
}
};
跟上一题差不多
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
int sum = 1, ans = 0;
for (int l = 0, r = 0; r < nums.size(); r ++) {
sum *= nums[r];
while (l < r && sum >= k) {
sum /= nums[l++];
}
if (sum < k)
ans += r - l + 1;
}
return ans;
}
};
这里我们就需要转化一下我们的思维了,我们可以用哈希表 来统计p的字符频率,在 s 上维护一个和 p 长度相同的窗口,比较窗口内字符的评率和 p 的字符频率,当频率匹配时记录起始索引。
那么就可以继续模板:
(1)果 [ l , r ] [l , r] [l,r]中存在某个字符数量大于 p 中字符数量,那么 [ l , r , r + 1 , r + 2..... ] [l, r, r + 1, r + 2.....] [l,r,r+1,r+2.....]也一定存在某个字符的数量大于p中字符数量;
(2)如果 [ l , r ] [l, r] [l,r]的每个字符的数量都小于或等于p中的字符数量,那么 [ l , l + 1 , l + 2 , . . . , r ] [l, l + 1, l+ 2, ..., r] [l,l+1,l+2,...,r]也成立。
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
unordered_map<char, int> mp;
for (int i = 0; i < p.size(); i ++ ) {
mp[p[i]] ++;
}
vector<int> res;
for (int l = 0, r = 0; r < s.size(); r ++) {
mp[s[r]] --;
while (l <= r && mp[s[r]] < 0) {
mp[s[l]] ++;
l ++;
}
if (r - l + 1 == p.size()) {
res.push_back(l);
}
}
return res;
}
};
}
if (r - l + 1 == p.size()) {
res.push_back(l);
}
}
return res;
}
};