备战蓝桥杯第五模块之数据结构

前言

本系列是我学习完大佬的方法后,为了蓝桥杯前几天可以快速过一遍所做,所以部分内容会很简洁。如果能够帮助到你,我也会很开心!!!

单调栈

对于每个数,观察他的左边比他大的数的第一个坐标是什么,如果有的话就输出那个数的坐标,如果没有的话就输出-1(找比他大的值的坐标)

for (int i = 0; i <= n; i++)
{
	while (top && a[stk[top] <= a[i]]) top--;
	if (!top) printf("-1 ");//如果栈空,则没有比该元素小的值。
    else printf("%d ", stk[tt]);
	skt[++top] = i;
}

单调队列 

常用题目:滑动窗口/求某个区间的最小值

for (int i = 1; i <= n; i++)
{
    while (hh <= tt && q[hh] < i - k + 1) hh++;//判断当前区间是否合法
    while (hh <= tt && a[q[tt]] > a[i]) tt--;
    q[++tt] = i;//存入下标
}

  其他:

   单调队列和单调栈中核心操作中都有存入下标a[++b]=i的操作,只不过单调栈是在队头存,单调队列是在队尾存

ST表(感觉考的可能性不大)

常用题目:区间最值查询

步骤:分解区间,可以分解成两个区间,把[L,R]分为两部分

           预处理的时候要提前判断区间的合法性

核心代码:

int Maxnum(int l, int r)
{
    int k = log(r - 1 + 1) / log(2);// 找到最大的j,使得2^j <= r - l + 1
    return max(st(l][k], st[r - (1 << k) + 1][k]);// 比较两个区间的最值
}

大跟堆/小跟堆可以用优先队列来快速实现,优先队列默认是大跟堆,小跟堆表示方法:

priority_queue<int,vector<int>,greater<int> >q;

向上更新

void up(int u)
{
    while (u != 1)//只要现在的点不是根节点就可以遍历
    {
        if (a[u] > a[u/2]) //如果儿子大于父亲
        swap(a[u], a[u/2]);
        u >>= 1;
    }
}

向下更新

void down(int u)
{
    int t = u;
    if (u * 2 <= size && h[u * 2] < h[t]) t = 2 * u;//左孩子如果小于父亲,继续向下遍历
    if (u * 2 + 1 <= size && h[u * 2] + 1 < h[t]) t = 2 * u + 1;//右孩子如果小于父亲,继续向下遍历
    if (u != t)
    {
        swap(h[u],h[t]);
        down(t);
    }
}

并查集

核心操作:

1.合并

p[root(a)] = root(b);

2.路径压缩:

int root(int x)
{
    if (p[x] != x) p[x] = root(p[x]);//如果现在的点不是根节点,就继续向上遍历
    return p[x];
}

树状数组

作用:

单点更新和区间查询

须知

lowbit(x)是求x的二进制表达式中最低位的1所对应的值

int lowbit(int x)
{
    return x & -x;
}

核心代码

单点更新(增加值)

void update(int k, int x)
{
    for (int i = k; i <= n; i += lowbit(i))
        t[i]++;
}

区间查询

//返回区间[l,k]的值
int query(int k)
{
    int sum = 0;
    for (int i = k; i <= n; i -= lowbit(i))
       sum+=bit[i]++;
    return sum;
}

trie树(字典树)

可用题目:

查找前缀相同的单词等

核心代码:

插入一个数

void insert(int x)
{
    int u = 0;
    for(int j=n;j>=0;j--)
    {
        if (!ch[u][str[i] - 'a'])
            ch[u][str[i] - 'a'] = ++tot;
        now = ch[u][str[i] - 'a'];
    }
    cnt[x]++;
}

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值