本文最后更新于 34 天前,其中的信息可能已经有所发展或是发生改变。
🎯 学习策略
重点突破:只学竞赛中真正高频的容器,避免“全面但无用”
核心原则:80%的题目用20%的容器功能解决
一、必学高频(核心中的核心)
1. vector(动态数组)—— STL最基础容器
核心定位:蓝桥杯100%必考,替代C语言静态数组,支持动态扩容
必须掌握的定义方式
#include <vector>
using namespace std;
vector<int> vec; // 空数组
vector<int> vec(5); // 5个元素,默认值0
vector<int> vec(5, 10); // 5个元素,每个值为10
vector<vector<int>> maze(10, vector<int>(10, 0)); // 二维数组(迷宫题必备)
核心接口(只记这8个)
| 接口 | 功能 | 竞赛场景 |
|---|---|---|
vec.push_back(x) | 尾部添加元素 | 存储输入数据、动态添加结果 |
vec[i] | 访问第i个元素(下标从0开始) | 遍历、修改元素 |
vec.size() | 获取元素个数 | 循环终止条件 |
vec.empty() | 判断是否为空 | 避免访问空数组 |
vec.back() | 访问最后一个元素 | 栈式操作、取最新结果 |
vec.pop_back() | 删除最后一个元素 | 回溯、撤销操作 |
vec.clear() | 清空所有元素 | 复用数组,避免重定义 |
sort(vec.begin(), vec.end()) | 排序(默认升序) | 预处理、找最值 |
✅ 正确遍历方式
// 1. 下标遍历(最常用)
for(int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
// 2. 范围for循环(C++11,简洁)
for(int num : vec) {
cout << num << " ";
}
// 3. 迭代器(配合sort时用)
sort(vec.begin(), vec.end());
🚨 常见错误
// ❌ 错误:越界访问
vector<int> vec = {1, 2, 3};
cout << vec[5]; // 随机值,可能崩溃
// ✅ 正确:先判断
if(i < vec.size()) {
cout << vec[i];
}
实战:找最大值+排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 输入n个数
int n;
cin >> n;
vector<int> nums(n);
for(int i = 0; i < n; i++) {
cin >> nums[i];
}
// 找最大值
int maxVal = nums[0];
for(int num : nums) {
if(num > maxVal) maxVal = num;
}
cout << "最大值: " << maxVal << endl;
// 排序
sort(nums.begin(), nums.end()); // 升序
cout << "升序: ";
for(int num : nums) cout << num << " ";
cout << endl;
// 降序
sort(nums.begin(), nums.end(), greater<int>());
cout << "降序: ";
for(int num : nums) cout << num << " ";
return 0;
}
2. priority_queue(优先队列/堆)
核心定位:TopK、贪心、最短路径(Dijkstra)必备
两种堆的定义
#include <queue>
using namespace std;
// 默认:大顶堆(最大元素在顶部)
priority_queue<int> maxHeap;
// 小顶堆(必须记住这个写法!)
priority_queue<int, vector<int>, greater<int>> minHeap;
核心操作
priority_queue<int> pq;
pq.push(3); // 插入元素
pq.push(1);
pq.push(4);
cout << pq.top(); // 4(最大元素)
pq.pop(); // 删除4
cout << pq.top(); // 3(新的最大元素)
// 必用:访问前先判空
if(!pq.empty()) {
int val = pq.top();
}
实战:TopK问题(找前K大的数)
vector<int> findTopK(vector<int>& nums, int k) {
// 小顶堆:只保留最大的K个元素
priority_queue<int, vector<int>, greater<int>> minHeap;
for(int num : nums) {
minHeap.push(num);
if(minHeap.size() > k) {
minHeap.pop(); // 弹出最小的
}
}
// 取出结果
vector<int> res;
while(!minHeap.empty()) {
res.push_back(minHeap.top());
minHeap.pop();
}
return res; // 返回的是升序的前K大
}
二、了解即可(特殊场景用)
bitset(位集)—— 空间优化神器
适用场景:状态压缩、二进制枚举、大数组标记
#include <bitset>
using namespace std;
bitset<10> bs; // 10位的二进制
bs.set(3); // 第3位设为1
bs.reset(3); // 第3位设为0
bs.flip(3); // 第3位取反
int count = bs.count(); // 统计1的个数
bool b = bs.test(3); // 检查第3位是否为1
// 空间对比:bitset<1000> 只用125字节,bool[1000]用1000字节
三、无需学习的容器(别浪费时间)
| 容器 | 为什么不用学 |
|---|---|
array | 静态数组,不如vector灵活 |
multimap/multiset | 可用map<int, vector<int>>替代 |
forward_list | 单向链表,效率低 |
list | 双向链表,竞赛无用场景 |
🎮 蓝桥杯容器速查表
1. 排序题 → vector + sort
vector<int> nums = {3,1,4,2};
sort(nums.begin(), nums.end()); // 升序
sort(nums.begin(), nums.end(), greater<int>()); // 降序
2. 找最值/贪心 → priority_queue
// 找最小值:小顶堆
priority_queue<int, vector<int>, greater<int>> minHeap;
// 找最大值:大顶堆(默认)
priority_queue<int> maxHeap;
3. 快速查找/去重 → unordered_set/map
unordered_set<int> s; // 去重
s.insert(1);
if(s.count(1)) { ... } // O(1)查找
unordered_map<string, int> mp; // 统计频率
mp["apple"]++;
4. 空间优化/二进制 → bitset
bitset<100> bs; // 100位二进制
if(bs.test(i)) { ... } // 检查第i位
💡 终极建议
第一周:主攻vector
- 每天刷1-2道纯
vector题目 - 掌握:输入输出、遍历、排序、二维数组
第二周:掌握priority_queue
- 刷TopK、贪心类题目
- 区分大顶堆 vs 小顶堆
第三周:了解unordered_set/map和bitset
- 用于去重、统计、状态压缩
记住三句话:
- 90%的题用
vector就能解决 - 贪心/TopK用
priority_queue - 其他容器了解即可,考到现学
📊 学习优先级
1. vector ★★★★★ (必须精通)
2. priority_queue ★★★★☆ (高频使用)
3. unordered_set/map ★★★☆☆ (辅助工具)
4. bitset ★★☆☆☆ (特殊场景)
5. 其他容器 ☆☆☆☆☆ (不用学)
用这个攻略,专注核心容器,2-3周就能掌握蓝桥杯所需的全部STL知识!