面向有 C 语言基础、准备用 C++ 刷 LeetCode Hot100 的选手。不涉及面向对象,只讲刷题实际用到的部分。
一、输入输出
C 里用 scanf / printf,C++ 里换成 cin / cout,头文件从 <stdio.h> 换成 <iostream>。
cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
cout << n << endl;
return 0;
}
using namespace std;这行是为了省去每次写std::cin、std::cout的前缀,刷题时固定加上即可。
不过力扣的题目不需要写 main 函数和输入输出,直接实现题目给的函数就行,这里只是说明语法差异。
二、万能头文件
刷题时不想一个个 #include,直接用这个:
cpp
#include <bits/stdc++.h>
using namespace std;
这个头文件包含了 STL 的所有内容(vector、map、queue 等等),力扣和大多数竞赛平台都支持。
三、auto 关键字
C++ 可以用 auto 让编译器自动推断变量类型,写复杂类型时非常省事。
cpp
// C 语言写法(要写完整类型)
int arr[3] = {1, 2, 3};
// C++ 用 auto 遍历 vector
vector<int> nums = {1, 2, 3};
for (auto x : nums) { // x 自动推断为 int
cout << x << " ";
}
// auto 推断迭代器类型(后面讲 map 时会用到)
auto it = myMap.find(key);
四、vector:动态数组
对应 C 里手动 malloc 的动态数组,但不用手动管理内存。
4.1 声明与初始化
cpp
vector<int> a; // 空数组
vector<int> b(5); // 长度为 5,默认值全 0
vector<int> c(5, -1); // 长度为 5,默认值全 -1
vector<int> d = {1, 2, 3, 4}; // 初始化列表
vector<vector<int>> mat(3, vector<int>(4, 0)); // 3×4 的二维数组,全 0
4.2 常用操作
cpp
vector<int> v = {1, 2, 3};
v.push_back(4); // 尾部追加元素,v = {1,2,3,4}
v.pop_back(); // 删除尾部元素,v = {1,2,3}
v.size(); // 返回元素个数,类型是 size_t(无符号),注意别和 int 混用
v.empty(); // 判断是否为空,返回 bool
v[0]; // 下标访问,和 C 数组一样
v.front(); // 第一个元素
v.back(); // 最后一个元素
v.clear(); // 清空
// 遍历
for (int i = 0; i < v.size(); i++) { ... } // 下标遍历
for (auto x : v) { ... } // 范围 for(只读)
for (auto& x : v) { ... } // 范围 for(可修改元素)
4.3 排序
cpp
#include <algorithm> // sort 在这里(用万能头可忽略)
vector<int> v = {3, 1, 4, 1, 5};
sort(v.begin(), v.end()); // 升序
sort(v.begin(), v.end(), greater<int>()); // 降序
// 自定义排序规则(按绝对值升序)
sort(v.begin(), v.end(), [](int a, int b) {
return abs(a) < abs(b);
});
五、string:字符串
C++ 的 string 比 C 的字符数组好用很多,不用担心越界,支持直接拼接和比较。
cpp
string s = "hello";
string t = "world";
s.size(); // 字符串长度(等价于 s.length())
s.empty(); // 是否为空
s[0]; // 下标访问字符
s + t; // 拼接,结果为 "helloworld"
s += "!"; // 追加
s == t; // 比较(C 里要用 strcmp,这里直接 ==)
s.substr(1, 3); // 从下标 1 开始取 3 个字符,结果 "ell"
s.find("ll"); // 查找子串,返回起始下标,找不到返回 string::npos
// 字符和数字互转
char c = '5';
int num = c - '0'; // 字符转数字:5
char back = num + '0'; // 数字转字符:'5'
// string 转 int / int 转 string(C++11 起)
int x = stoi("123"); // string → int
string str = to_string(456); // int → string
六、unordered_map:哈希表
对应哈希表,查询/插入平均 O(1)。力扣里用它来替代手写哈希。
cpp
unordered_map<int, int> mp;
mp[1] = 100; // 插入或修改
mp[2] = 200;
mp.count(1); // 判断 key 是否存在,存在返回 1,不存在返回 0
mp.find(1); // 返回迭代器,找不到返回 mp.end()
// 遍历
for (auto& [key, val] : mp) { // C++17 结构化绑定
cout << key << " " << val << endl;
}
mp.erase(1); // 删除 key=1 的键值对
mp.size(); // 键值对数量
unordered_map无序,如果需要按 key 有序遍历,用map(底层红黑树,O(log n))。
常见用法:统计频次
cpp
vector<int> nums = {1, 2, 2, 3, 3, 3};
unordered_map<int, int> freq;
for (int x : nums) {
freq[x]++; // key 不存在时自动初始化为 0,然后 +1
}
// freq: {1:1, 2:2, 3:3}
七、unordered_set:哈希集合
只存 key,不存 value,用于去重和快速查询某元素是否存在。
cpp
unordered_set<int> st;
st.insert(1);
st.insert(2);
st.insert(2); // 重复插入无效
st.count(2); // 存在返回 1,不存在返回 0
st.erase(1); // 删除
st.size(); // 元素数量
八、stack / queue:栈和队列
栈
cpp
stack<int> stk;
stk.push(1); // 入栈
stk.push(2);
stk.top(); // 查看栈顶:2
stk.pop(); // 弹出栈顶(无返回值)
stk.empty(); // 是否为空
stk.size(); // 元素数量
队列
cpp
queue<int> q;
q.push(1); // 入队
q.push(2);
q.front(); // 队头:1
q.back(); // 队尾:2
q.pop(); // 弹出队头(无返回值)
q.empty(); // 是否为空
优先队列(堆)
cpp
// 大根堆(默认)
priority_queue<int> pq;
pq.push(3);
pq.push(1);
pq.push(4);
pq.top(); // 4(最大值)
pq.pop(); // 弹出 4
// 小根堆
priority_queue<int, vector<int>, greater<int>> minPQ;
九、函数参数传引用
C 里传数组用指针,C++ 里对于 vector、string 等对象,传参时加 & 避免拷贝:
cpp
// 不加 & 会拷贝整个 vector,浪费时间和空间
void func(vector<int>& nums) { // 加 & 传引用,修改会影响原变量
nums.push_back(0);
}
void func(const vector<int>& nums) { // 加 const 表示只读,不会修改
cout << nums[0];
}
力扣的题目函数签名里基本都带 &,这是原因。
十、INT_MAX / INT_MIN
C++ 里同样可以用,在 <climits> 里(万能头已包含):
cpp
int maxVal = INT_MAX; // 2147483647
int minVal = INT_MIN; // -2147483648
// DP 初始化常用
vector<int> dp(n, INT_MAX);
十一、常用数学函数
cpp
abs(-5); // 绝对值:5(整数用 abs,浮点用 fabs)
max(3, 5); // 最大值:5
min(3, 5); // 最小值:3
sqrt(16.0); // 平方根:4.0
pow(2, 10); // 幂:1024.0(返回 double)
// 多个值取 max/min
max({1, 3, 2}); // C++11 initializer_list,结果 3
十二、与 C 语言的核心差异对照表
| 场景 | C 语言 | C++ 刷题写法 |
|---|---|---|
| 动态数组 | malloc + 手动管理 |
vector<int> |
| 字符串 | char[] + strcmp/strcpy |
string |
| 哈希表 | 手写或不用 | unordered_map |
| 集合/去重 | 排序后遍历 | unordered_set |
| 栈 | 手写数组模拟 | stack<int> |
| 队列 | 手写数组模拟 | queue<int> |
| 排序 | qsort(函数指针) |
sort(lambda) |
| 最值 | 手写比较 | max / min |
| 字符串转数字 | atoi |
stoi |
小结
以上就是 Hot100 刷题过程中 90% 以上场景会用到的 C++ 语法,没有涉及任何面向对象的内容。核心就是:用 STL 容器替代 C 里手动实现的数据结构,其余逻辑和 C 没有本质区别。