1. 题目
输入一个数组nums[],根据所给的target(目标数),返回两个元素的索引x、y,
假定:nums[x]+nums[y]=target且x,y唯一
2. 算法分析
得到目标元素需要将每个元素和其他元素相加计算结果和,通常有如下几种方案
暴力搜索
显然,通过两个for循环的嵌套可简单实现该目的
算法复杂度:O( n2 )夹逼搜索
预处理:将nums[]排序(推荐快速排序) nlogn
tip: 排序时要注意保存每个value对应的原始index
夹逼:设置两个指针从一头一尾开始搜索 n
if sum > target right - -
else if sum < target left ++
else return[left.index,right.index]
算法复杂度:O(
nlogn )哈西搜索
将nums[]保存在哈西表中,使用 unordered_multimap
在STL标准库中提供map,multimap,unordered_map,unordered_multimap map:搜索通过rb树实现,时间复杂度为O(lgn) multimap:一种特殊的map,key值可以重复 unordered_map:通过哈西表实现,时间复杂度为O(n) unordered_multimap:一种特殊的unordered_map,key可以重复
key:数组的值 value:index
例: nums[4]=233 key=233,value=4搜索:对于nums中的每个值num,
计算complement=target-num。
if comlement 存在 return[num.value,complement.value]
else num++
until 全部数组搜索完毕or已经返回值tip: unordered_multimap允许相同的key值,每次搜索返回 第一个元素。
算法复杂度:O( n <script type="math/tex" id="MathJax-Element-5">n</script>)
3. 源代码
代码在VS2013下实现
- 夹逼搜索:预处理时我直接使用了以前编写归并排序
vector<int> twoSum(vector<int>& nums, int target)//O(nlgn)
{
int end = nums.size()-1;
vector<int> sort;
for (int t = 0; t <= end; t++)
{
sort.push_back(nums[t]);
sort.push_back(t);//保存原始索引
}
mergsort(sort, 0, sort.size()-2);
int i = 0, j = sort.size() - 2;
while (i != j&&i<j)
{
if ((sort[i] + sort[j]) > target)
j = j - 2;
else if ((sort[i] + sort[j]) < target)
i = i + 2;
else
{
result.push_back(sort[i+1]);
result.push_back(sort[j+1]);
break;
}
}
return result;
}
- 哈西搜索(多个解的情况仍然适用)
vector<int> twoSum1(vector<int>& nums, int target)//O(n)使用哈希表
{
unordered_multimap<int, int> m_nums;
for (int i = 0; i<nums.size(); i++)
{
m_nums.insert(pair<int,int>(nums[i], i));
}
unordered_multimap<int, int>::iterator iter = m_nums.begin();
unordered_multimap<int, int>::iterator judge;
while( iter != m_nums.end())
{
int temp = target-iter->first;
judge = m_nums.find(temp);
int n = m_nums.count(temp);//计算该key值有几个重复的元素
int i = 0;
while (judge != m_nums.end() && i < n)
{
if ( (judge->second) > (iter->second))//存在
{
result.push_back(iter->second);
result.push_back(judge->second);
return result;//假定该题目只有唯一解
}
judge++;
i++;
}
++iter;
}
return result;
}
此笔记用于自己学习记录,如果有更好的解法和思路,欢迎在文章下指出不足