7月5日刷题笔记——滑动窗口
题目1:567. 字符串的排列(中等题)
没写出来,直接看滑动窗口的题解。
class Solution {
public:
bool checkInclusion(string s1, string s2) {
int n = s1.length(), m = s2.length();
// 如果s1长度大于s2则s2肯定不含s1子串
if (n > m) {
return false;
}
/* 定义两个数组
** cnt1存放s1内各个字母出现的次数
** cnt2存放当前窗口内各个字母出现的次数(窗口大小为s1的长度)
*/
vector<int> cnt1(26), cnt2(26);
// 保存cnt1,并存入初始窗口数据
for (int i = 0; i < n; ++i) {
// s1[i] / s2[i] 为字母,则s1[i] - 'a'为该字母转换为数字的数组的下标(从0开始)
// eg: s1="ab" 此时为 ++cnt1[0] 即字母a出现一次
++cnt1[s1[i] - 'a'];
++cnt2[s2[i] - 'a'];
}
// 两数组相等说明符合
if (cnt1 == cnt2) {
return true;
}
// i = n 即从此往后滑动窗口(eg:s2="eidb"此时将d写入窗口,e弹出窗口),
// 直至s2字符串全部遍历后结束
for (int i = n; i < m; ++i) {
// 将当前字母写入数组
++cnt2[s2[i] - 'a'];
// 弹出最顶端的字母,即他的数量--
--cnt2[s2[i - n] - 'a'];
// 比较数组是否相等
if (cnt1 == cnt2) {
return true;
}
}
return false;
}
};
根据题解复现代码:
class Solution {
public:
bool checkInclusion(string s1, string s2) {
int n = s1.size(), m = s2.size();
if(n > m){
return false;
}
vector<int> cnt1(26), cnt2(26);
int i;
for(i = 0; i < n; ++i){
++cnt1[s1[i] - 'a'];
++cnt2[s2[i] - 'a'];
}
if(cnt1 == cnt2) return true;
for(i = n; i < m; ++i){
// 当前字母进入窗口
++cnt2[s2[i] - 'a'];
// 顶端字母弹出窗口
--cnt2[s2[i - n] - 'a'];
if(cnt1 == cnt2) return true;
}
return false;
}
};
题目2:733. 图像渲染(简单题)
我的题解:
递归。
class Solution {
public:
void find(vector<vector<int>>& image, int sr, int sc, int color, int target, vector<vector<int>>& flag) {
if(sr >= image.size() || sc >= image[0].size() || flag[sr][sc] == 1) return;
cout << sr << "," << sc << endl;
if(image[sr][sc] == target){
image[sr][sc] = color;
flag[sr][sc] = 1;
find(image, sr, sc - 1, color, target, flag);
find(image, sr, sc + 1, color, target, flag);
find(image, sr - 1, sc, color, target, flag);
find(image, sr + 1, sc, color, target, flag);
}
}
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
// int N = image.size(), M = image[0].size();
vector<vector<int>> flag(image.size(), vector<int>(image[0].size()));
int target = image[sr][sc];
find(image, sr, sc, color, target, flag);
return image;
}
};