持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
剑指 Offer 59 - I. 滑动窗口的最大值
思路:
「单调队列」这种特殊的数据结构来辅助了,
代码:
class Solution {
private:
deque<int> data;
public:
void push(int n) {
//队头要最大,这时如果发现比队头大则我把之前那些都踢出,然后把我这个数放在队头,反之我就放在队尾。
while (!data.empty() && data.back() < n) {
data.pop_back();
}
data.push_back(n);
}
int max() {
return data.front();
}
void pop(int n) {
if (!data.empty() && data.front() == n) {
data.pop_front();
}
}
//主要利用队列头来比较这个最大的值
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
Solution window;
vector<int> res;
for (int i = 0; i < nums.size(); i++) {
if (i < k - 1) {
//先放区间[0, k - 1)的数进去 (//先把窗口的前 k - 1 填满)
window.push(nums[i]);
}
else {
window.push(nums[i]);
res.push_back(window.max());
window.pop(nums[i - k + 1]); //如果发现nums[i - k + 1] == que.front()就把它踢出去,因为不在下一个k长度区间范围内,反之不踢它
// nums[i - k + 1] 就是窗口第一个元素 解释 :(就是如果我下一步就滑出了这个窗口,那么我就应该把窗口第一个元素踢出)
}
}return res;
}
};
1658. 将 x 减到 0 的最小操作数
思路:
移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。如果可以将 x 恰好减到 0,返回最小操作数否则,返回 -1。**相当于找到一个和为 sum - x 的最长连续子数组。**利用滑动窗口来解决。
代码:
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int n = nums.size();
int ans = -1, sum = 0;
int sum1 = 0;
for (int i = 0; i < n; i++) {
sum1 += nums[i];
}
if (sum1 < x) return -1;
x = sum1 - x;
for (int i = 0, j = 0; j < n; j++) {
sum += nums[j];
while (sum > x) {
sum -= nums[i++];
}
if (sum == x) {
ans = max(ans, j - i + 1);}
}
return ans == -1 ? -1 : n - ans;
}
};