209长度最小的子数组
先贴代码
cpp
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums)
{
int left=0;
int right=0;
int sum=0;
int res=0;
while(right<nums.size())
{
sum+=nums[right++];
while(sum>=target)
{
res=res==0?right-left:min(res,right-left);
sum-=nums[left++];
}
}
return res;
}
};
再贴一个滑动窗口的模板
cpp
int left = 0, right = 0;
while (right < s.size()) {
// 增⼤窗⼝
window.add(s[right]);
right++;
while (window needs shrink) {
// 缩⼩窗⼝
window.remove(s[left]);
left++;
}
}
cpp
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int l = 0;
int r = 0;
int ans = 0;
unordered_map<int, int> cnt;
while (r < fruits.size()) {
cnt[fruits[r]]++;
r++;
while (cnt.size() > 2) {
cnt[fruits[l]]--;
if (cnt[fruits[l]] == 0) {
cnt.erase(fruits[l]);
}
l++;
}
ans = ans == 0 ? r - l : max(ans, r - l);
}
return ans;
}
};
cpp
class Solution {
public:
string minWindow(string s, string t) {
if (t.length() > s.length())
return "";
unordered_map<char, int> window, need;
for (auto a : t)
need[a]++;
int l = 0, r = 0;
int valid = 0;
int start = 0;
int len = INT_MAX;
while (r < s.size()) {
auto c = s[r++];
if (need.count(c)) {
window[c]++;
if (window[c] == need[c]) {
valid++;
}
}
while (valid == need.size()) {
if (r - l < len) {
start = l;
len = r - l;
}
auto d = s[l++];
if (need.count(d)) {
if (window[d] == need[d]) {
valid--;
}
window[d]--;
}
}
}
return len == INT_MAX ? "" : s.substr(start, len);
}
};
整体思路上是一样的,问题的关键是怎么表示窗口扩展和缩减,以及条件的满足。
cpp
class Solution {
static constexpr int DIRS[4][2] = {
{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 右下左上
public:
vector<vector<int>> generateMatrix(int n) {
vector ans(n, vector<int>(n));
int i = 0, j = 0, di = 0;
for (int val = 1; val <= n * n; val++) { // 要填入的数
ans[i][j] = val;
int x = i + DIRS[di][0];
int y = j + DIRS[di][1]; // 下一步的位置
// 如果 (x, y) 出界或者已经填入数字
if (x < 0 || x >= n || y < 0 || y >= n || ans[x][y]) {
di = (di + 1) % 4; // 右转 90°
}
i += DIRS[di][0];
j += DIRS[di][1]; // 走一步
}
return ans;
}
};
灵神是怎么写这么nb的
54 螺旋矩阵
cpp
class Solution {
static constexpr int DIRS[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 右下左上
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
vector<int> ans(m * n);
int i = 0, j = 0, di = 0;
for (int k = 0; k < m * n; k++) { // 一共走 mn 步
ans[k] = matrix[i][j];
matrix[i][j] = INT_MAX; // 标记,表示已经访问过(已经加入答案)
int x = i + DIRS[di][0];
int y = j + DIRS[di][1]; // 下一步的位置
// 如果 (x, y) 出界或者已经访问过
if (x < 0 || x >= m || y < 0 || y >= n || matrix[x][y] == INT_MAX) {
di = (di + 1) % 4; // 右转 90°
}
i += DIRS[di][0];
j += DIRS[di][1]; // 走一步
}
return ans;
}
};