栈
#include <stack> using namespace std; stack<int> st; // 定义一个存储 int 类型的栈 st.push(5); // 入栈:将元素 5 压入栈顶 int a = st.top(); // 取栈顶元素(不删除) st.pop(); // 弹出栈顶元素(无返回值) bool is_empty = st.empty(); // 判断栈是否为空 int size = st.size(); // 获取栈中元素个数 stack<TreeNode*> st;
队列
#include <queue> using namespace std; queue<int> q; // 定义一个存储 int 类型的队列 q.push(10); // 入队:将元素 10 加入队尾 int b = q.front(); // 取队首元素(不删除) int c = q.back(); // 取队尾元素(不删除) q.pop(); // 弹出队首元素(无返回值) bool is_empty = q.empty(); // 判断队列是否为空 int size = q.size(); // 获取队列中元素个数 queue<TreeNode*> que;
字典(std::map/std::unordered_map)
#include <map> // 有序字典 #include <unordered_map> // 无序字典(哈希表,等价Python dict) using namespace std; // 1. 定义字典:键类型为string,值类型为int unordered_map<string, int> dict; // 2. 插入/修改键值对 dict["张三"] = 90; // 若键不存在则插入,存在则覆盖值 dict.insert({"李四", 85}); // 插入方式2 // 3. 访问元素 int score = dict["张三"]; // 按键取值,若键不存在会自动插入默认值0 int score2 = dict.at("李四"); // 按键取值,若键不存在会抛出异常 // 4. 查找键是否存在 auto it = dict.find("张三"); if (it != dict.end()) { cout << "存在,值为:" << it->second << endl; } else { cout << "不存在" << endl; } // 5. 删除元素 dict.erase("张三"); // 按键删除 dict.clear(); // 清空所有元素 // 6. 遍历字典 for (auto& pair : dict) { cout << pair.first << ": " << pair.second << endl; // pair.first=键,pair.second=值 } // 7. 判断是否为空 & 获取元素个数 bool is_empty = dict.empty(); int size = dict.size(); // 有序字典map(按键升序排列) map<string, int> ordered_dict; ordered_dict["王五"] = 75; ordered_dict["赵六"] = 80; // 遍历时会自动按key升序输出:王五:75 → 赵六:80
| 操作 / 功能 | 语法示例 | 说明 |
|---|
| 头文件 | #include <map> | 必须包含 |
| 定义 | map<Key, Val> mp; | Key = 键类型(如 string),Val = 值类型(如 int),按键升序排列 |
| 插入键值对 | mp[key] = val; | 键不存在则插入,存在则覆盖值 |
mp.insert({key, val}); | 键已存在时不会覆盖,返回插入结果 |
mp.emplace(key, val); | 原地构造,效率比 insert 高 |
| 访问值 | mp[key] | 按键取值,键不存在则自动插入,值为默认值(int=0,string="") |
mp.at(key) | 按键取值,键不存在则抛出异常(更安全) |
| 查找键 | mp.find(key) | 返回迭代器:找到则指向该键值对,否则 = mp.end () |
mp.count(key) | 存在返回 1,不存在返回 0(map 键唯一) |
| 删除元素 | mp.erase(key) | 按键删除,返回删除的元素个数(0 或 1) |
mp.erase(iterator) | 按迭代器删除(如 mp.erase (mp.find (key))) |
mp.clear() | 清空所有元素 |
| 遍历 | for (auto& p : mp) { p.first; p.second; } | 按升序遍历所有键值对,p.first = 键,p.second = 值 |
| 获取大小 / 判空 | mp.size() | 返回键值对数量 |
mp.empty() | 空返回 true,否则 false |
| 边界操作 | mp.begin()/mp.end() | 首 / 尾迭代器 |
mp.lower_bound(key) | 返回第一个≥key 的迭代器 |
mp.upper_bound(key) | 返回第一个 > key 的迭代器 |
| 操作 / 功能 | 语法示例 | 说明 |
|---|
| 头文件 | #include <unordered_map> | 必须包含 |
| 定义 | unordered_map<Key, Val> ump; | 键值对无序,底层哈希表,平均 O (1) 操作(等价 Python dict) |
| 核心操作 | 同 map(insert/emplace/erase/clear/size/empty/find/count) | 语法完全一致,仅无序、无 lower_bound/upper_bound |
| 区别于 map | 1. 无序;2. 不支持范围查找;3. 效率更高(平均 O (1)) | 刷题优先用 unordered_map(除非需要有序) |
| 性能注意 | 键需支持哈希(如 int/string),自定义类型需重载哈希函数 | 避免用复杂类型作为键(如 TreeNode * 需谨慎) |
pair对
#include <utility> // pair 所在头文件 using namespace std; // 1. 定义pair:存储两个不同类型的值 pair<int, string> p1; // 默认初始化 pair<int, string> p2(10, "hello"); // 直接初始化 auto p3 = make_pair(20, "world"); // 简化创建方式(自动推导类型) // 2. 访问pair成员 int num = p2.first; // 访问第一个元素(10) string str = p2.second; // 访问第二个元素("hello") // 3. 修改pair成员 p3.first = 25; p3.second = "leetcode"; // 4. pair作为容器元素(如栈、队列、map) stack<pair<TreeNode*, int>> st; // 栈中存储「节点指针+路径和」 st.push(make_pair(root, root->val)); auto top = st.top(); TreeNode* node = top.first; // 取节点 int cur_sum = top.second; // 取路径和 // 5. pair作为函数返回值(返回多个值) pair<int, int> get_min_max(vector<int>& nums) { int min_val = *min_element(nums.begin(), nums.end()); int max_val = *max_element(nums.begin(), nums.end()); return {min_val, max_val}; // 返回pair } // 接收返回值 auto [min_num, max_num] = get_min_max(nums); // C++17结构化绑定
pair<int, string> p(10, "hello"); cout << p.first; // 输出 10 cout << p.second; // 输出 hello p.first = 20; // 修改第一个值为20 p.second = "world";// 修改第二个值为world
// 定义栈:存储“TreeNode* 类型的节点指针”和“int 类型的路径和” stack<pair<TreeNode*, int>> st; // 创建一个pair对象,第一个值是root(节点指针),第二个值是root->val(路径和) st.push(pair<TreeNode*, int>(root, root->val)); // 取出栈顶的pair,访问其成员 pair<TreeNode*, int> node = st.top(); node.first; // 等价于 节点指针(比如 root) node.second; // 等价于 路径和(比如 root->val)
| 操作 / 功能 | 语法示例 | 说明 |
|---|
| 头文件 | #include <utility> | 必须包含,否则无法使用 pair |
| 定义 / 初始化 | pair<T1, T2> p; | 定义空 pair,T1/T2 为任意类型(如 int/string/TreeNode*) |
pair<T1, T2> p(v1, v2); | 直接初始化,p.first=v1,p.second=v2 |
auto p = make_pair(v1, v2); | 简化初始化(自动推导类型,推荐) |
| 访问元素 | p.first | 获取第一个元素(只读 / 可修改) |
p.second | 获取第二个元素(只读 / 可修改) |
| 修改元素 | p.first = new_val; | 直接赋值修改第一个元素 |
p.second = new_val; | 直接赋值修改第二个元素 |
| 作为容器元素 | stack<pair<TreeNode*, int>> st; | 栈中存储「节点指针 + 路径和」(路径总和题用法) |
st.push(make_pair(node, sum)); | 入栈 pair 元素 |
| 作为函数返回值 | pair<int, int> func() { return {a,b}; } | 函数返回两个值(如返回最小 / 最大值) |
| 解构访问(C++17+) | auto [a, b] = func(); | 结构化绑定,直接拆分 pair 为两个变量(无需写 first/second) |
auto 关键字
make_pair 函数
- 核心作用:模板函数,自动接收两个参数并构造
pair对象(无需手动写pair<T1,T2>),返回值可直接作为push参数。 // 繁琐写法(显式构造) st.push(pair<TreeNode*,int>(root, root->val)); // 简化写法(推荐) st.push(make_pair(root, root->val));
- 本质:等价于
pair<T1,T2>(a,b),只是自动推导 T1/T2 类型,减少代码量
- auto 不能替代 make_pair:auto 是 “类型推导工具”,make_pair 是 “pair 对象构造工具”,push 需要的是 “对象”,因此必须用 make_pair(或显式构造)生成对象,auto 仅简化变量声明。
- 栈 / 队列定义规则:空容器必须显式声明类型(如
stack<pair<TreeNode*,int>> st;),无法用 auto 推导;只有初始化赋值的容器(C++17+)可推导:auto st = stack<int>{1,2,3};。 - 空指针规范:C++ 中用
NULL或nullptr(推荐),避免用null(Java 语法)。
| 关键字 / 函数 | 本质作用 | 能否直接用于 push 参数? | 举例 |
|---|
auto | 推导已存在的变量的类型(仅声明时用) | ❌ 不能(无法构造对象) | auto p = st.top();(推导 p 的类型) |
make_pair | 构造并返回一个pair对象(生成新对象) | ✅ 能(返回的对象符合 push 要求) | st.push(make_pair(a, b)); |
✅ 不用make_pair也可以,但必须显式构造pair对象(不能省略 “构造对象” 这一步);
✅auto仅用于推导已存在变量的类型,绝对不能直接作为函数参数(比如st.push(auto(...))是语法错误)。