|
1 |
| -## 题目地址 |
| 1 | +# 题目地址 |
2 | 2 | https://leetcode-cn.com/problems/two-sum/
|
3 | 3 |
|
4 |
| -## 思路 |
| 4 | +> 只用数组和set还是不够的! |
| 5 | +
|
| 6 | +# 第1题. 两数之和 |
| 7 | + |
| 8 | +给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 |
| 9 | + |
| 10 | +你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 |
| 11 | + |
| 12 | +**示例:** |
| 13 | + |
| 14 | +给定 nums = [2, 7, 11, 15], target = 9 |
| 15 | + |
| 16 | +因为 nums[0] + nums[1] = 2 + 7 = 9 |
| 17 | + |
| 18 | +所以返回 [0, 1] |
| 19 | + |
| 20 | + |
| 21 | +# 思路 |
5 | 22 |
|
6 | 23 | 很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。
|
7 |
| -我们来看一下使用数组和set来做哈希法的局限。 |
| 24 | + |
| 25 | +使用哈希法最为合适,之前已经介绍过,数组和set在哈希法中的应用,那么来看一下使用数组和set来做哈希法的局限。 |
8 | 26 |
|
9 | 27 | * 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
|
10 |
| -* set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下表位置,因为我们要返回x 和 y的下表。所以set 也不能用。 |
| 28 | +* set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下表位置,因为要返回x 和 y的下表。所以set 也不能用。 |
| 29 | + |
| 30 | +此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下表。 |
| 31 | + |
| 32 | +C++中map,有三种类型: |
| 33 | + |
| 34 | +|映射 |底层实现 | 是否有序 |数值是否可以重复 | 能否更改数值|查询效率 |增删效率| |
| 35 | +|---|---| --- |---| --- | --- | ---| |
| 36 | +|std::map |红黑树 |key有序 |key不可重复 |key不可修改 | O(logn)|O(logn) | |
| 37 | +|std::multimap | 红黑树|key有序 | key可重复 | key不可修改|O(logn) |O(logn) | |
| 38 | +|std::unordered_map |哈希表 | key无序 |key不可重复 |key不可修改 |O(1) | O(1)| |
| 39 | + |
| 40 | +std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。 |
| 41 | + |
| 42 | +同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA)。 |
| 43 | + |
| 44 | +**这道题目中并不需要key有序,选择std::unordered_map 效率更高!** |
11 | 45 |
|
12 |
| -此时我们就要选择一种数据结构 map ,map是一种key value的存储结构,我们可以用key保存数值,用value在保存数值所在的下表。 |
13 |
| -这道题目是map在哈希法中的经典应用 |
| 46 | +# C++代码 |
14 | 47 |
|
| 48 | +``` |
| 49 | +class Solution { |
| 50 | +public: |
| 51 | + vector<int> twoSum(vector<int>& nums, int target) { |
| 52 | + std::unordered_map <int,int> map; |
| 53 | + for(int i = 0; i < nums.size(); i++) { |
| 54 | + auto iter = map.find(target - nums[i]); |
| 55 | + if(iter != map.end()) { |
| 56 | + return {iter->second, i}; |
| 57 | + break; |
| 58 | + } |
| 59 | + map.insert(nums[i], i); |
| 60 | + } |
| 61 | + return {}; |
| 62 | + } |
| 63 | +}; |
| 64 | +``` |
15 | 65 |
|
16 | 66 | ## 一般解法
|
17 | 67 |
|
|
0 commit comments