题目
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
解法
哈希表
代码(C++)
class Solution{
public:
vector<int> twoSum(vector<int>& nums, int target){
unordered_map<int, int> mp;
vector<int> vi (2, -1);
for(int i=0; i<nums.size(); i++){
int temp = target - nums[i];
if(mp.count(temp)){
vi[0] = mp[temp];
vi[1] = i;
break;
}
else mp.insert(pair<int, int>(nums[i], i));
}
return vi;
}
};
代码Python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
mp = {}
for i in range(len(nums)):
temp = target - nums[i]
if temp in mp:
return [mp[temp], i]
else:
mp.setdefault(nums[i], i)
return [-1, -1]
map数据结构
map
map:提供一对一的hash:key-value,其中key称为关键字,value称为值,key是唯一的
[C++ ] map
#include <map> //头文件
using namespace std;
map<int, string> mp; //构造
map<set<int>, string> mp2; //map的键值也可以是STL容器类型
访问
mp['c']; //通过键来访问,map<char, int>
map<char, int>::iterator it = mp.begin(); //通过迭代器
it->first; //迭代器访问键
it->second; //迭代器访问值
常用函数
单个插入操作
map<int, string> mp;
// 如果已经存在键值2015,则会作赋值修改操作,如果没有则插入
mp[2015] = "Tom";
insert
四个重载函数
// 插入单个键值对,并返回插入位置和成功标志,插入位置已经存在值时,插入失败
pair<iterator,bool> insert (const value_type& val);
//在指定位置插入,在不同位置插入效率是不一样的,因为涉及到重排
iterator insert (const_iterator position, const value_type& val);
// 插入多个
void insert (InputIterator first, InputIterator last);
//c++11开始支持,使用列表插入多个
void insert (initializer_list<value_type> il);
具体使用
#include <iostream>
#include <map>
int main()
{
std::map<char, int> mymap;
// 插入单个值
mymap.insert(std::pair<char, int>('a', 100));
mymap.insert(std::pair<char, int>('z', 200));
//返回插入位置以及是否插入成功
std::pair<std::map<char, int>::iterator, bool> ret;
ret = mymap.insert(std::pair<char, int>('z', 500));
if (ret.second == false) {
std::cout << "element 'z' already existed";
std::cout << " with a value of " << ret.first->second << '\n';
}
//指定位置插入
std::map<char, int>::iterator it = mymap.begin();
mymap.insert(it, std::pair<char, int>('b', 300)); //效率更高
mymap.insert(it, std::pair<char, int>('c', 400)); //效率非最高
//范围多值插入
std::map<char, int> anothermap;
anothermap.insert(mymap.begin(), mymap.find('c'));
// 列表形式插入
anothermap.insert({ { 'd', 100 }, {'e', 200} });
return 0;
}
find(key)
返回键为key的映射的迭代器,时间复杂度为O(logN),其中N为 映射的个数
map<char, int>::iterator it = mp.find('b');
erase()
mp.erase(it),删除单个元素,it为迭代器,时间复杂度:O(1)
mp.erase(key),删除单个元素,时间复杂度:O(logN)
mp.erase(first, last) first, last均为迭代器,删除[first, last)中元素,时间复杂度:O(last-first)
size()
返回map映射对数,时间复杂度:O(1)
clear()
清空,时间复杂度: O(N)
count(key)
查询关键字为key的元素的个数,在map里结果非0即1,可做判别用
map<char, int> mp ;
mp.insert(pair<char, int>('b', 1));
if(mp.count('b')) return ture;
[C++] unordered_map
unordered_map与map的异同:
头文件不同,unordered_map需:
#include<unordered_map>
map:
内部实现:红黑树
优点:有序性
缺点: 空间占用率高
适用处:对于那些有顺序要求的问题,用map会更高效一些
unordered_map:
内部实现:哈希表
优点: 因为内部实现了哈希表,因此其查找速度非常的快
缺点: 哈希表的建立比较耗费时间
适用处:对于查找问题,unordered_map会更加高效一些
unordered_map的用法和map是一样的,提供了 insert,size,count等操作,并且里面的元素也是以pair类型来存贮的。其底层实现是完全不同的,上方已经解释了,但是就外部使用来说却是一致的。
常用操作实例
#include <iostream>
#include <unordered_map>
#include <map>
#include <string>
using namespace std;
int main()
{
//注意:C++11才开始支持括号初始化
unordered_map<int, string> myMap={{ 5, "张大" },{ 6, "李五" }};//使用{}赋值
myMap[2] = "李四"; //使用[ ]进行单个插入,若已存在键值2,则赋值修改,若无则插入。
myMap.insert(pair<int, string>(3, "陈二"));//使用insert和pair插入
//遍历输出+迭代器的使用
auto iter = myMap.begin();//auto自动识别为迭代器类型unordered_map<int,string>::iterator
while (iter!= myMap.end())
{
cout << iter->first << "," << iter->second << endl;
++iter;
}
//查找元素并输出+迭代器的使用
auto iterator = myMap.find(2);//find()返回一个指向2的迭代器
if (iterator != myMap.end())
cout << endl<< iterator->first << "," << iterator->second << endl;
system("pause");
return 0;
}