10.3刷题计划
力扣76题 最小覆盖串(困难)
1.需求统计
(1)先统计t中每个字符的数量,存入数组/哈希表cnt。
(2)用变量k表示当前还需要多少字符。
2.扩展右边界r
(1)每次把s[r]加入窗口:
(2)如果cnt[s[r]]>0,说明它是需要的字符,k--。
(3)不管需不需要,都执行cnt[s[r]]--,表示“窗口里多一个s[r]”。
3.收缩左边界l
(1)当k==0时,说明窗口[l,r]已经包含了所有所需字符。
(2)在收缩过程中不断更新bestlen和bestStart。
(3)这时候尝试收缩左边界l,一旦一掉一个关键字符(++cnt[s[l]]>0),就不再满足覆盖,k++,收缩结束。
class Solution {
public:
string minWindow(string s, string t) {
if(s == t) return s;
int n = s.size(), k = t.size();
vector<int> cnt(128, 0); // cnt 记录 t 中每个字符需要多少个
for(char x : t)
cnt[x] ++;
int l = 0, r = 0;
int bestlen = INT_MAX, bestStart = -1;
string res = "";
while(r < n)
{
if(-- cnt[s[r]] >= 0) // 用掉一个需要的字符
k --;
while(k == 0) // [l, r] 窗口已经覆盖了所有字符,可以尝试收缩
{
if(bestlen > r - l + 1) // 更新答案
{
bestlen = r - l + 1;
bestStart = l;
}
if(++ cnt[s[l]] > 0) // 一旦移掉一个关键字符,就不再满足覆盖,k++,收缩结束
k ++;
l ++;
}
r ++;
}
return bestStart == -1 ? "" : s.substr(bestStart, bestlen);
}
};
力扣 239题 滑动窗口最大值(困难题)
自己维护一个单调队列
1.pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作。
2.push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值
为止。
维护的单调队列是从大到小的了。
class Solution {
private:
class MyQueue { //单调队列(从大到小)
public:
deque<int> que; // 使用deque来实现单调队列
// 每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
// 同时pop之前判断队列当前是否为空。
void pop(int value) {
if (!que.empty() && value == que.front()) {
que.pop_front();
}
}
// 如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
// 这样就保持了队列里的数值是单调从大到小的了。
void push(int value) {
while (!que.empty() && value > que.back()) {
que.pop_back();
}
que.push_back(value);
}
// 查询当前队列里的最大值 直接返回队列前端也就是front就可以了。
int front() {
return que.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
MyQueue que;
vector<int> result;
for (int i = 0; i < k; i++) { // 先将前k的元素放进队列
que.push(nums[i]);
}
result.push_back(que.front()); // result 记录前k的元素的最大值
for (int i = k; i < nums.size(); i++) {
que.pop(nums[i - k]); // 滑动窗口移除最前面元素
que.push(nums[i]); // 滑动窗口前加入最后面的元素
result.push_back(que.front()); // 记录对应的最大值
}
return result;
}
};
力扣4题 寻找两个正序数组的中位数
思路:
1.合并两数组
2.sort排序
3.判断
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
for(auto e:nums2) nums1.push_back(e);
sort(nums1.begin(),nums1.end());
int n = nums1.size();
if(n%2==1) return nums1[nums1.size()/2];
return (nums1[nums1.size()/2-1]+nums1[nums1.size()/2]*1.0)/2.0;
}
};

浙公网安备 33010602011771号