1. Two Sum*
题目描述
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have *exactly* one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
https://leetcode.com/problems/two-sum/description/
给定一个整数序列, 要求返回两个索引, 它们对应的两个值的和等于 target. (此题的测试可以假设肯定是有一个解的, 另外, 不能将同一个值使用两次, 比如数组中有一个数字 4, target 为 8, 不能说 4 + 4 = 8). 比如 [2, 7, 11, 15], target 为 9, 那么返回 [0, 1].
解题思路
等下会做另一道类似的题, 但是是在有序数组中查找两个数, 使得它们的和与 target 相等. 但这道题的不同之处在于, 它的数组是无序的, 而排序太浪费时间, 如果要在遍历过程中实现目的, 那么需要快速查找的方法, 这个时候只好考虑使用空间来换取时间, 因此引入哈希表来对元素进行查找, 时间复杂度为 O(1), 空间复杂度为 O(n), 保存元素本身以及它对应的索引. 当访问元素 nums[i] 时, 在哈希表中查找 target - nums[i] 是否存在, 如果存在, 那么就保存索引; 否则将 nums[i] 以及索引 i 加入到哈希表中.
C++ 实现 1
record
这个哈希表的 Key 为数组中的元素, Value 为元素在数组中的索引. 在遍历数组的过程中, 每当访问 nums[i]
, 便去 record
中查找 target - nums[i]
是否在数组中已经出现过. 时间复杂度为
0
(
1
)
0(1)
0(1), 空间复杂度为
O
(
n
)
O(n)
O(n).
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> record;
for (int i = 0; i < nums.size(); ++i) {
int left = target - nums[i];
if (record.count(left)) {
return {record[left], i};
} else {
record[nums[i]] = i;
}
}
return {};
}
};
当然也可以这样:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> record;
vector<int> res;
for (int i = 0; i < nums.size(); ++ i) {
if (record.count(target - nums[i])) {
res = {record[target - nums[i]], i};
break;
}
record[nums[i]] = i;
}
return res;
}
};
C++ 实现 2
年轻的时候写的 🤣. 记录在这里是因为发现代码中还专门用了 std::swap
, .insert()
, .end()
, std::make_pair
之类的方法, 思路和上一节是一样的.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
if (nums.size() < 2)
throw invalid_argument("nums' size invalid");
unordered_map<int, int> hash_map;
for (int i = 0; i < nums.size(); ++i) {
auto iter = hash_map.find(target - nums[i]);
if (iter != hash_map.end()) {
int j = iter->second;
if (i > j)
std::swap(i, j);
int res[2] = {i, j};
return vector<int>(res, res+2);
}
else
hash_map.insert(std::make_pair(nums[i], i));
}
}
};