目录
1. two_sum问题 - unordered_map
题目: 给定数组和target,找出和等于target的两个数下标(LeetCode 1)
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> num_map;
for(int i = 0; i < nums.size(); ++i) {
auto it = num_map.find(target - nums[i]);
if(it != num_map.end())
return {it->second, i};
num_map[nums[i]] = i;
}
return {};
}
STL技巧: unordered_map提供O(1)查找,比暴力O(n²)快得多
2. 合并区间 - sort + back_inserter
题目: 合并所有重叠区间(LeetCode 56)
**vector<vector<int>> merge(vector<vector<int>>& intervals) {
if(intervals.empty()) return {};
sort(intervals.begin(), intervals.end());
vector<vector<int>> merged;
merged.push_back(intervals[0]);
for(const auto& interval : intervals) {
if(interval[0] <= merged.back()[1]) {
merged.back()[1] = max(merged.back()[1], interval[1]);
} else {
merged.push_back(interval);
}
}
return merged;
}**
STL技巧:sort保证区间有序,back()快速访问末尾元素
3. 全排列 - next_permutation
题目:生成数组所有不重复排列(LeetCode 46)
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
do {
result.push_back(nums);
} while(next_permutation(nums.begin(), nums.end()));
return result;
}
STL技巧: next_permutation自动生成字典序下一个排列
4. 最大子数组和 - max_element + 动态规划
题目:找出和最大的连续子数组(LeetCode 53)
int maxSubArray(vector<int>& nums) {
vector<int> dp(nums.size());
dp[0] = nums[0];
for(int i = 1; i < nums.size(); ++i) {
dp[i] = max(nums[i], dp[i-1] + nums[i]);
}
return *max_element(dp.begin(), dp.end());
}
STL技巧:max_element快速找到最大值
5. 字母异位词分组 - sort + unordered_map
题目: 将字母相同但顺序不同的单词分组(LeetCode 49)
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> groups;
for(auto& s : strs) {
string key = s;
sort(key.begin(), key.end());
groups[key].push_back(s);
}
vector<vector<string>> result;
transform(groups.begin(), groups.end(), back_inserter(result),
[](auto& pair){ return pair.second; });
return result;
}
STL技巧:sort标准化单词,transform转换map到vector
6. 滑动窗口最大值 - deque + pop_back
题目:找出每个滑动窗口中的最大值(LeetCode 239)
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> dq;
vector<int> result;
for(int i = 0; i < nums.size(); ++i) {
if(!dq.empty() && dq.front() == i - k)
dq.pop_front();
while(!dq.empty() && nums[dq.back()] < nums[i])
dq.pop_back();
dq.push_back(i);
if(i >= k - 1)
result.push_back(nums[dq.front()]);
}
return result;
}
STL技巧:deque双端操作维护窗口最大值
7. 缺失数字 - accumulate
题目:找出0-n中缺失的数字(LeetCode 268)
int missingNumber(vector<int>& nums) {
int n = nums.size();
int expected = n * (n + 1) / 2;
int actual = accumulate(nums.begin(), nums.end(), 0);
return expected - actual;
}
STL技巧:accumulate快速求和,数学公式解题
8. 合并两个有序数组 - merge
题目:将两个有序数组合并到第一个数组(LeetCode 88)
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
vector<int> temp(nums1.begin(), nums1.begin() + m);
std::merge(temp.begin(), temp.end(),
nums2.begin(), nums2.end(),
nums1.begin());
}
STL技巧:merge算法高效合并有序序列
9. 旋转数组 - rotate
题目:将数组向右旋转k步(LeetCode 189)
void rotate(vector<int>& nums, int k) {
k %= nums.size();
std::rotate(nums.rbegin(), nums.rbegin() + k, nums.rend());
}
STL技巧:rotate+反向迭代器高效旋转
10. 最长连续序列 - unordered_set
题目:找出最长连续数字序列的长度(LeetCode 128)
int longestConsecutive(vector<int>& nums) {
unordered_set<int> num_set(nums.begin(), nums.end());
int longest = 0;
for(int num : num_set) {
if(!num_set.count(num - 1)) {
int current = num;
int streak = 1;
while(num_set.count(current + 1)) {
current++;
streak++;
}
longest = max(longest, streak);
}
}
return longest;
}
STL技巧:unordered_set提供O(1)存在性检查
总结对比表
进阶建议:
- 学习C++17的并行算法(execution::par)
- 掌握中的数值算法
- 理解每种算法的时间/空间复杂度