题目描述
给定一个整数数组
nums
和一个目标值target
,请你在该数组中找出和为目标值的那两个整数,并返回它们的下标。
- 每个输入只对应一个答案。
- 同一个元素不能重复使用。
- 你可以按任意顺序返回答案。
示例
输入:
nums = [2, 7, 11, 15], target = 9
输出:
[0, 1]
解释: 因为 nums[0] + nums[1] = 2 + 7 = 9
,所以返回 [0, 1]
。
解题思路概览
我们来介绍三种方法:
方法 | 思路 | 时间复杂度 | 空间复杂度 |
---|---|---|---|
暴力法 | 双重遍历数组所有可能组合 | O(n²) | O(1) |
哈希表法(count 写法) | 边遍历边用哈希查“补数” | O(n) | O(n) |
哈希表法(find 写法) | 使用 find() + insert 更规范 | O(n) | O(n) |
方法一:暴力法(Brute Force)
思路:
使用两层循环,枚举数组中所有不同的两元素组合,判断是否满足 nums[i] + nums[j] == target
。
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); ++i) {
for (int j = i + 1; j < nums.size(); ++j) {
if (nums[i] + nums[j] == target) {
return {i, j};
}
}
}
return {};
}
};
分析:
- ✅ 思路直观,适合入门;
- ❌ 时间复杂度高,不适合大数据量。
方法二:哈希表写法(使用 count()
)
思路:
- 用一个哈希表
map
存储遍历过的数字及其索引; - 每次遍历当前元素
nums[i]
时,判断target - nums[i]
(即“补数”)是否已经存在于 map 中; - 若存在 → 直接返回两个下标;
- 若不存在 → 把当前元素加入 map。
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> map; // key: 数值, value: 下标
for (int i = 0; i < nums.size(); ++i) {
if (map.count(target - nums[i])) {
return {map[target - nums[i]], i};
}
map[nums[i]] = i; // 记录当前值及其下标
}
return {};
}
};
分析:
- ✅ 查找和插入都为 O(1);
- ✅ 非常适合刷题;
- ❗ 使用
map[key]
有可能在其他题中产生意外插入。
方法三:哈希表写法(使用 find()
+ insert
)
思路:
与方法二相同,但使用 STL 更推荐的方式:
- 用
find()
查找 key 是否存在; - 用
insert()
插入新元素,避免不小心覆盖已有值; - 更规范、安全,适合用于工程开发或面试展示 STL 掌握能力。
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> map;
for (int i = 0; i < nums.size(); ++i) {
auto iter = map.find(target - nums[i]); // 查找补数
if (iter != map.end()) {
return {iter->second, i}; // 返回补数的下标和当前下标
}
map.insert({nums[i], i}); // 插入当前值
}
return {};
}
};
分析:
- ✅ 与方法二效果相同;
- ✅ 代码风格更符合 STL 正统写法;
- 🟡 稍微冗长,适合工程/面试环境。
总结对比表
方法 | 时间复杂度 | 空间复杂度 | 是否易懂 | 是否规范 | 是否适合面试 |
---|---|---|---|---|---|
暴力枚举 | O(n²) | O(1) | ✅ 简单 | ✅ | ❌ 太慢 |
哈希法(count) | O(n) | O(n) | ✅ 简洁 | 🟡 有插入副作用 | ✅ 快速刷题 |
哈希法(find) | O(n) | O(n) | 🟡 略长 | ✅ 安全规范 | ✅ 面试优选 |
一句话总结:
“用哈希表存已经看过的数,找当前数的补数是否在哈希表中” 是两数之和的核心思路,掌握后可以一键通关各类“求和组合”题!