Leetcode刷題74. 搜尋二維矩陣
阿新 • • 發佈:2021-01-01
技術標籤:ACM--資料結構
文章目錄
單調佇列
1.演算法分析
單調佇列可以維護一個滑動視窗的最大值和最小值
2.模板
#include <bits/stdc++.h>
using namespace std;
int const N = 1e6 + 10;
int tt, hh, a[N], q[N];
int main() {
int n, k;
scanf("%d %d", &n, &k);
for (int i = 0; i < n; ++i) scanf ("%d", &a[i]);
// 先輸出視窗的最小值
hh = 0, tt = 0; // 視窗的頭部元素和尾部元素
for (int i = 0; i < n; ++i) {
if (hh <= tt && i - k + 1 > q[hh]) hh++;
while (hh <= tt && a[q[tt]] >= a[i]) tt--; // 維護一個單調遞增的佇列
q[++tt] = i;
if (i >= k - 1) printf("%d ", a[q[hh]]);
}
cout << endl;
// 視窗的最大值
hh = 0, tt = -1;
for (int i = 0; i < n; ++i) {
if (hh <= tt && i - k + 1 > q[hh]) hh++;
while (hh <= tt && a[q[tt]] <= a[i]) tt--; // 維護一個單調遞減的佇列
q[++tt] = i;
if (i >= k - 1) printf("%d ", a[q[hh]]);
}
return 0;
}
3.典型例題
acwing154滑動視窗
題意: 給定一個大小為 n ≤ 1 0 6 n≤10^6 n≤106的陣列。有一個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動一個位置。確定滑動視窗位於每個位置時,視窗中的最大值和最小值。
題解: 模板
程式碼:
#include <bits/stdc++.h>
using namespace std;
int const N = 1e6 + 10;
int tt, hh, a[N], q[N];
int main() {
int n, k;
scanf("%d %d", &n, &k);
for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
// 先輸出視窗的最小值
hh = 0, tt = 0; // 視窗的頭部元素和尾部元素
for (int i = 0; i < n; ++i) {
if (hh <= tt && i - k + 1 > q[hh]) hh++;
while (hh <= tt && a[q[tt]] >= a[i]) tt--; // 維護一個單調遞增的佇列
q[++tt] = i;
if (i >= k - 1) printf("%d ", a[q[hh]]);
}
cout << endl;
// 視窗的最大值
hh = 0, tt = -1;
for (int i = 0; i < n; ++i) {
if (hh <= tt && i - k + 1 > q[hh]) hh++;
while (hh <= tt && a[q[tt]] <= a[i]) tt--; // 維護一個單調遞減的佇列
q[++tt] = i;
if (i >= k - 1) printf("%d ", a[q[hh]]);
}
return 0;
}