原题描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
解题思路
一种很简单的做法就是两重循环遍历数组,不过较暴力,时间复杂度也达到了 O ( n 2 ) O(n^2) O(n2)。
我们试着使用一重循环解决这个问题,当遍历每个元素 S i S_i Si 时,需要判断 S i S_i Si 前面是否有元素 t a r g e t − S i target - S_i target−Si,能实现这一功能的首推数据结构就是哈希表,遍历时将该元素添加到表中,同时判断表中是否有 t a r g e t − S i target - S_i target−Si,若存在,则直接返回两者下标;不存在则继续遍历。
需要注意的是,C++ 中有两种常用的 map,即 map 和 unordered_map。前者的底层实现是平衡树,查、找的时间复杂度都为 O ( l o g n ) O(logn) O(logn);后者底层实现为哈希表,查、找时间复杂度为 O ( 1 ) O(1) O(1)。
AC代码
暴力 O ( n 2 ) O(n^2) O(n2):
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
for (int i = 0; i < nums.size() - 1; i++)
for (int j = i + 1; j < nums.size(); j++)
if (nums[i] + nums[j] == target)
res.push_back(i), res.push_back(j);
return res;
}
};
哈希表 O ( n ) O(n) O(n):
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> heap;
for (int i = 0; i < nums.size(); i++)
{
int r = target - nums[i];
if (heap.count(r)) return {heap[r], i};
heap[nums[i]] = i;
}
return {};
}
};
两种解法的效率还是差的很明显的。