• Acwing-----算法基础课之第二讲(数据结构一)


    826. 单链表

    使用数组模拟链表,速度比较快;邻接表,一般用来存储树和图;

    #include <iostream>
    using namespace std;
    
    const int N = 100010;
    
    // head:头节点的下标
    // e:节点i的值
    // ne:节点i的next指针
    // idx:当前已经用到了哪个点
    int head, e[N], ne[N], idx;
    
    void init() {
        head = -1;
        idx = 0;
    }
    
    void add_to_head(int x) {
        e[idx] = x, ne[idx] = head, head = idx, idx++;   
    }
    
    // 将x插入下标为k的节点后面
    void add(int k, int x) {
        e[idx] = x, ne[idx] = ne[k], ne[k] = idx, idx++;
    }
    
    // 将下标是k的点后面的点删掉
    void remove(int k) {
        ne[k] = ne[ne[k]];
    }
    
    int main() {
        int m;
        cin >> m;
        init();
        while (m--) {
            int x, k;
            char op;
            cin >> op;
            if (op == 'H') {
                cin >> x;
                add_to_head(x);
            } else if (op == 'D') {
                cin >> k;
                if (!k) head = ne[head];
                else remove(k - 1);
            } else {
                cin >> k >> x;
                add(k - 1, x);
            }
        }
        
        for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
        cout << endl;
        return 0;
    }                                              
    

    827.双链表

    双链表:一般用来优化某些问题;

    #include <iostream>
    using namespace std;
    
    const int N = 100010;
    
    int e[N], l[N], r[N], idx, m;
    
    void init() {
        // 0表示左端点,1表示右端点
        r[0] = 1, l[1] = 0;
        idx = 2;
    }
    
    // 在下标是k的点右边插入x
    void insert(int k, int x) {
        e[idx] = x;
        r[idx] = r[k];
        l[idx] = k;
        l[r[k]] = idx;
        r[k] = idx++;
    }
    
    void remove(int k) {
        r[l[k]] = r[k];
        l[r[k]] = l[k];
    }
    
    int main() {
        init();
        cin >> m;
        while (m--) {
            string op;
            cin >> op;
            int k, x;
            
            if (op == "L") {
                cin >> x;
                insert(0, x);
            } else if (op == "R") {
                cin >> x;
                insert(l[1], x);
            } else if (op == "D") {
                cin >> k;
                remove(k + 1);
            } else if (op == "IL") {
                cin >> k >> x;
                insert(l[k + 1], x);
            } else {
                cin >> k >> x;
                insert(k + 1, x);
            }
        }
        
        for (int i = r[0]; i != 1; i = r[i]) cout << e[i] << ' ';
        cout << endl;
        return 0;
    }
    

    828.模拟栈

    单调栈

    #include <iostream>
    using namespace std;
    
    const int N = 100010;
    int n;
    int stk[N], tt;
    
    int main() {
        cin >> n;
     
        for (int i = 0; i < n; ++i) {
            int x;
            cin >> x;
            while (tt && stk[tt] >= x) tt--;
            if (tt) cout << stk[tt] << ' ';
            else cout << -1 << ' ';
            stk[++tt] = x;
        }   
        return 0;
    }
    

    154.滑动窗口

    单调队列

    #include <iostream>
    using namespace std;
    
    const int N = 1000010;
    
    int a[N], q[N], n, k;
    
    int main() { 
        scanf("%d%d", &n, &k);
        for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
        
        int 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]]);
        }
        puts("");
        
        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]]);
        }
        puts("");
        return 0;
    }
    

    831.KMP

    next[i] = j表示p[1, j] = p[i - j + 1, i]

    #include <iostream>
    
    using namespace std;
    
    const int N = 100010, M = 1000010;
    
    int n, m;
    int ne[N];
    char s[M], p[N];
    
    int main() {
        cin >> n >> p + 1 >> m >> s + 1;
    
        for (int i = 2, j = 0; i <= n; ++i) {
            while (j && p[i] != p[j + 1]) j = ne[j];
            if (p[i] == p[j + 1]) ++j;
            ne[i] = j;
        }
    
        for (int i = 1, j = 0; i <= m; ++i) {
            while (j && s[i] != p[j + 1]) j = ne[j];
            if (s[i] == p[j + 1]) ++j;
            if (j == n) {
                printf("%d ", i - n);
                j = ne[j];
            }
        }
    
        return 0;
    }
  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/clown9804/p/13529078.html
Copyright © 2020-2023  润新知