为什么C++是LeetCode的理想语言(以及如何避免失败)
\n\n如果你打开LeetCode并想:“我全用Python写吧,简洁明了”——打住。为了硬核成长和真正理解算法,C++比任何其他语言都更有优势。为什么?因为它迫使你思考内存、速度和实现细节。没有那种不理解工作原理的“魔法”sort()。
在本文中,我们不仅会列举题目。我们将展示如何在LeetCode解题时用C++思维,哪些数据结构真正需要,并提供现成的代码模板。你将了解到为什么std::vector是你最好的朋友,而std::unordered_map是秘密武器。
准备好了吗?开始吧。
\n\nLeetCode中C++的五大数据结构
\n\n在开始解题之前,你需要准备好“武器库”。以下是90%情况下真正会用到的:
\n\n- \n
- std::vector——动态数组。适用于所有涉及序列、区间、矩阵的问题。 \n
- std::unordered_map——哈希表。用于计数、查找重复项、两数之和类问题。 \n
- std::set / std::unordered_set——集合。当需要快速检查元素是否存在时使用。 \n
- std::stack / std::queue / std::deque——用于遍历、括号序列、BFS/DFS。 \n
- std::pair——存储键值对(例如坐标+值)时不可或缺。 \n
以下是一个使用哈希表进行频率分析的基本封装示例:
\n\n#include <unordered_map>\n#include <vector>\n#include <string>\n\nstd::unordered_map<std::string, int> countWords(const std::vector<std::string>& words) {\n std::unordered_map<std::string, int> freq;\n for (const auto& w : words) {\n freq[w]++;\n }\n return freq;\n}\n\n\n看到了吗?代码最少,收益最大。
\n\n如何解题:C++检查清单
\n\n新手常犯的错误是直接写代码。正确的做法是首先理解数据结构。这对C++至关重要,因为错误选择容器可能导致超时(TLE)。
\n\n步骤1. 确定题目类型
\n- \n
- 数组/字符串 → vector, string \n
- 查找重复项 → unordered_set \n
- 动态规划 → vector<vector<int>> \n
- 图 → vector<vector<int>> 或 unordered_map<int, vector<int>> \n
步骤2. 选择算法范式
\n- \n
- 贪心算法——如果题目涉及最小值/最大值 \n
- 二分查找——用于已排序数据 \n
- 双指针——用于区间问题 \n
- DFS/BFS——用于遍历 \n
步骤3. 编写框架
\n不要试图立即优化。先写出可行的解法,然后再重构。
\n\n实战题目解析:两数之和(LeetCode #1)
\n\n经典题目。即使你之前解过,用C++实现会有不同的体验。
\n\n题目描述:给定一个整数数组nums和一个整数target,返回两个数的索引,使它们的和等于target。
低效解法(O(n²)):
\nstd::vector<int> twoSum_brute(std::vector<int>& nums, int target) {\n for (int i = 0; i < nums.size(); ++i) {\n for (int j = i + 1; j < nums.size(); ++j) {\n if (nums[i] + nums[j] == target) {\n return {i, j};\n }\n }\n }\n return {};\n}\n\n\n高效解法(O(n) 使用 unordered_map):
\n#include <unordered_map>\n\nstd::vector<int> twoSum(std::vector<int>& nums, int target) {\n std::unordered_map<int, int> seen; // 值 -> 索引