STL之deque和set

本文深入探讨C++中deque容器的特性和使用方法,包括快速随机访问、高效插入和删除两端元素。通过一道结合deque与set的算法题,详细解析如何在遍历数组时维护一个大小固定的队列,展示set的元素查找功能。

按照惯例上网址:https://blog.youkuaiyun.com/u011630575/article/details/79923132

介绍:
deque容器为一个给定类型的元素进行线性处理,像向量一样,它能够快速地随机访问任一个元素,并且能够高效地插入和删除容器的尾部元素。但它又与vector不同,deque支持高效插入和删除容器的头部元素,因此也叫做双端队列

deque<int>  d;//一般定义
d.push_back(x)//在队列最后添加x;
d.push_front(x)//在队列最前面添加x;
deque<int>::iterator it;
it=d.end();
d.pop_back();//弹出最后一个

和set结合的一道题用
来源:cf#590(Div3)
题目地址:https://codeforces.com/contest/1234/my
题意:给你个长度为 n 的数组和一个队列 , 队列最多可以同时存在 k 个数。遍历这个数组 , 如果当前数组对应的数在队列中则不做改动 , 如果不在则将它插入队首 , 并且将队尾弹出。遍历完后按照队列顺序输出

#include<bits/stdc++.h>
#define ll long long 
#define ios std::ios::sync_with_stdio(false) , std::cin.tie(0) , std::cout.tie(0)
using namespace std;
const int N = 2e5+10;
int n , k;
ll a[N];
set<ll>qq;
deque<ll>txc;
deque<ll>::iterator it;
int main()
{
    ios;
    cin >> n >> k;
    cin >> a[1];
    qq.insert(a[1]);
    txc.push_front(a[1]);
    for(int i = 2 ; i <= n ; i++)
    {
        cin >> a[i];
        if(qq.count(a[i])) continue;
        if(qq.count(a[i]) == 0 && qq.size() < k)
        {
            qq.insert(a[i]);
            txc.push_front(a[i]);
        }
        else if(qq.count(a[i]) == 0 && qq.size() == k)
        {
            it = txc.end(); it--;
            qq.erase(*it);
            txc.pop_back();
            txc.push_front(a[i]);
            qq.insert(a[i]);
        }
    }
    cout << txc.size() << endl;
    for(it = txc.begin() ; it != txc.end(); it ++)
    {
        cout << *it << " ";
    }
    return 0;
}

这里我提一点关于set的用法吧,多练多见多会。
比如
a.count(x)的意思就是在a的set队列里找有没有x这个元素,有则输出1,没有则0.大概就是起一个查找的功能吧

### 使用方法 Deque 是双端队列,两端都可以进行元素的进出操作,提供了抛异常返回值两种不同的操作方式,具体如下: - **添加元素**:可以在队列的头部或尾部添加元素,抛异常的方法为 `addFirst(e)` `addLast(e)`,返回值的方法为 `offerFirst(e)` `offerLast(e)` [^1]。 - **删除元素**:可以删除队列的头部或尾部元素,抛异常的方法为 `removeFirst()` `removeLast()`,返回值的方法为 `pollFirst()` `pollLast()` [^1]。 - **查看元素**:可以查看队列的头部或尾部元素,抛异常的方法为 `getFirst()` `getLast()`,返回值的方法为 `peekFirst()` `peekLast()` [^1]。 以下是一个简单的 Deque 使用示例: ```java import java.util.Deque; import java.util.LinkedList; public class DequeExample { public static void main(String[] args) { Deque<Integer> deque = new LinkedList<>(); deque.offerLast(10); deque.offerLast(15); deque.offerLast(20); deque.offerFirst(5); System.out.println("弹出队首元素" + deque.pollFirst()); System.out.println("弹出队尾元素" + deque.pollLast()); System.out.println("查看此时队尾元素" + deque.peekLast()); System.out.println("判断队列是否为空" + deque.isEmpty()); } } ``` ### 特点 Deque 有多种实现类,常见的有 `ArrayDeque` `LinkedList`,它们具有不同的特点: - **`ArrayDeque`**:基于数组实现的线性双向队列,在处理大量数据时,由于数组的连续存储特性,其内存占用相对较低,并且在多数情况下性能表现较好 [^2]。 - **`LinkedList`**:基于链表实现的链式双向队列,其底层结构是双向链表。与 `ArrayList` 相比,随机访问速度慢(时间复杂度为 O(n)),但头尾插入/删除速度快(时间复杂度为 O(1)),中间插入/删除速度平均为 O(n),内存占用较高(需要存储指针) [^3]。 ### 应用场景 - **栈队列的实现**:由于 Deque 支持从两端进行元素的添加删除操作,因此可以方便地实现栈(后进先出)队列(先进先出)的功能。 - **LRU 缓存淘汰算法**:可以使用 `LinkedList` 来实现 LRU(Least Recently Used)缓存淘汰算法,利用其链表结构方便地移动元素,将最近使用的元素移到链表头部,当缓存满时,淘汰链表尾部的元素 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值