1. 程式人生 > 其它 >Leetcode刷題74. 搜尋二維矩陣

Leetcode刷題74. 搜尋二維矩陣

技術標籤: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 n106的陣列。有一個大小為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;
}