文章

哈希#简单#两数之和

哈希#简单#两数之和

前文

给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

正文

要点

  • 题目代码模板输入输出为vector
  • vector的基本使用
  • map的基本使用,mapfind()函数如果key未找到,会返回指向末尾的迭代器,即等价于map.end()

暴力破解,解法1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
		vector<int>	res;
		for(int i = 0; i < nums.size(); i++) {
			int remain = target - nums[i];
			res.push_back(i);
			for(int j = i + 1; j < nums.size(); j++) {
				if (nums[j] == remain) {
					res.push_back(j);
					return res;
				}
			}
			res.clear();
		}
		return res;
    }
};

思路:

遍历数组每一个元素,判断当前元素和之后的每个元素是否能组合成target, 做法先声明一个空的结果数组,首先push当前元素的位置,其次第二个循环遍历之后每个元素 是否符合差值,符合则push第二个元素的位置。 注意clear()放在第二个循环之后,如果第二个循环没有return,则清空res数组,重复下个过程。

问题:

主要问题是第二遍遍历比较费时间,解决如何快速判断剩下的元素是否包含余数,且如果包含,位置下标是多少。

思考:

  • nums没有说按顺序排列,剩下的元素不能用二分查找
  • 提前把每个元素和其位置存入map映射,这样方便判断是否存在和找到位置,需要考虑到map映射的key不能重复

使用map简化第二次遍历,解法2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
		map<int, int> map;
		for (int i = 0; i < nums.size(); ++i) {
			auto it = map.find(target - nums[i]);
			if (it != map.end()) {
				return {it->second, i};
			}
			map[nums[i]] = i;
		}
        return {};
    }
};

注意,mapkey不能重复,不能先把nums和下标存入map, 结果不和当前元素自身判断,所以先判断是否存在,再存入元素,此时即时元素重复, 如nums={3, 3, 7}target=10,不需要答案{0, 2}{1, 2}也可, 且结合题要求,答案只出现一次并且结果顺序不需要从左至右。

本文由作者按照 CC BY 4.0 进行授权

热门标签