zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    父类引用指向子类对象详解
    词尾的-sion和-tion的发音规则
    att&ack学习笔记6
    att&ack框架学习笔记5
    att&ack学习笔记4
    att&ck框架学习笔记3
    att&ck学习笔记2
    att&ck学习笔记1
    kerberos系列之spark认证配置
    kerberos系列之kerberos安装
  • 原文地址:https://www.cnblogs.com/clown9804/p/13529078.html
Copyright © 2011-2022 走看看