题目
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].
One-pass Hash Table
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map <int,int> hashMap;
for(int i=0;i<nums.size();i++)
{
int secondEle=target-nums[i];
if(hashMap.find(secondEle)!=hashMap.end()&&hashMap.find(secondEle)->second!=i)
{
return vector<int>{i,hashMap.find(secondEle)->second};
}
hashMap.insert(pair<int,int>(nums[i],i));
}
return vector<int>();
}
};
思路
- 使用哈希表加速索引查找,以空间换时间,将查找时间从 O ( n ) O(n) O(n)减少到 O ( 1 ) O(1) O(1)
- 遍历数组将其加入哈希表的同时,检查是否存在解(One-pass)。
对应的two-pass hash table和brute force法如下:
Two-pass Hash Table
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map <int,int> hashMap;
for(int i=0;i<nums.size();i++)
{
hashMap.insert(pair<int,int>(nums[i],i));
}
for(int i=0;i<nums.size();i++)
{
int secondEle=target-nums[i];
if(hashMap.find(secondEle)!=hashMap.end()&&hashMap.find(secondEle)->second!=i)
{
return vector<int>{i,hashMap.find(secondEle)->second};
}
}
return vector<int>();
}
};
Brute Force
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for(int i=0;i<nums.size();i++)
{
for(int j=i+1;j<nums.size();j++)
{
if(nums[j]==target-nums[i])
{
return vector<int>{i,j};
}
}
}
return vector<int>();
}
};
知识回顾
C++ vector
Vector是一个封装了动态大小数组的顺序容器(Sequence Container),它能够存放各种类型的对象。可以简单的认为,它是一个能够存放任意类型的动态数组。
构造函数
- vector():创建一个空vector
- vector(int nSize):创建一个vector,元素个数为nSize
- vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
- vector(const vector&):复制构造函数
- vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中
增加函数
- void push_back(const T& x):向量尾部增加一个元素X
- iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
- iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
- iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据
删除函数
- iterator erase(iterator it):删除向量中迭代器指向元素
- iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
- void pop_back():删除向量中最后一个元素
- void clear():清空向量中所有元素
遍历函数
- reference at(int pos):返回pos位置元素的引用
- reference front():返回首元素的引用
- reference back():返回尾元素的引用
- iterator begin():返回向量头指针,指向第一个元素
- iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
- reverse_iterator rbegin():反向迭代器,指向最后一个元素
- reverse_iterator rend():反向迭代器,指向第一个元素之前的位置
判断函数
- bool empty() const:判断向量是否为空,若为空,则向量中无元素
大小函数
- int size() const:返回向量中元素的个数
- int capacity() const:返回当前向量张红所能容纳的最大元素值
- int max_size() const:返回最大可允许的vector元素数量值
其他函数
- void swap(vector&):交换两个同类型向量的数据
- void assign(int n,const T& x):设置向量中第n个元素的值为x
- void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素
C++ map
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个称为该关键字的值)的数据处理能力。
map自动建立key- value的对应。key 和 value可以是任意类型。根据key值快速查找记录,查找的复杂度是Log(N)。
使用map需包含map类所在的头文件:#include <map>
通常使用map <TypeA,TypeB> name;
的形式构造。
插入
- 用insert函数插入pair数据:
mapName.insert(pair<TypeA, TypeB>(ValueA, ValueB));
- 用insert函数插入value_type数据:
mapName.insert(map<TypeA, TypeB>::value_type (ValueA, ValueB));
- 用数组方式插入数据:
mapName[ValueA]=ValueB;
第一种和第二种在效果上是完全一样的,需要注意的是:用insert函数插入数据,当map中有这个关键字时,insert操作无法插入数据,数组方式会覆盖之前该关键字对应的值。
map的大小
调用size()函数:int Nsize=mapName.size();
遍历
- 前向迭代器:
map<int, string>::iterator iter;
for(iter = mapName.begin(); iter != mapName.end(); iter++)
{
cout<<iter->first<<' '<<iter->second<<endl;
}
- 反向迭代器:
map<int, string>::iterator iter;
for(iter = mapName.rbegin(); iter != mapName.rend(); iter++)
{
cout<<iter->first<<' '<<iter->second<<endl;
}
- 数组形式:
int Nsize=mapName.size();
for(int nindex = 1; nindex <= nSize; nindex++) //此处nindex从1开始
{
cout<<mapName[nindex]<<endl;
}
查找
iter = mapName.find(ValueA);
if(iter != mapName.end())
cout<<"Find, the value is "<<iter->second<<endl;
else
cout<<"Do not Find"<<endl;
删除
iterator erase(iterator it); //通过一个条目对象删除
iterator erase(iterator first,iterator last); //删除一个范围
size_type erase(const Key& key); //通过关键字删除
clear()相当于mapName.erase(mapName.begin(),mapName.end());