阿里巴巴的一道面试题
25.给定一个整数数组和一个整数,返回两个数组的索引,这两个索引指向的数字的加和等于指定的整数。需要最优的算法,分析算法的空间和时间复杂度。
#include <iostream>
#include <unordered_map>
using namespace std;
struct STwoIndex
{//数组的两个索引
int unFirst;//第一个索引
int unSecond;//第二个索引
STwoIndex()
:unFirst(-1)
,unSecond(-1)
{}//初始化,同时等于0,说明不存在
};
STwoIndex GetArrayIndex(int array[], unsigned int nCount, int nTarget)
{//整数数组,有可能有负数,也可能有重复的数
STwoIndex twoIndex;
std::unordered_map<int, int> umValueIndex;
umValueIndex.reserve(nCount);
if (nTarget & 0x1)
{//目标是奇数,重复的暂时不考虑
for (int i = 0; i < nCount; ++i)
{
umValueIndex[array[i]] = i;
}
}
else
{//目标是偶数,存在2个 nTarget/2的数字的可能性
int nFirst = -1;
int nHalf = nTarget >> 1;
for (int i = 0; i < nCount; ++i)
{
if (nHalf == array[i])
{
if (nFirst >= 0)
{//已找到,两个 nTarget/2
twoIndex.unFirst = nFirst;
twoIndex.unSecond = i;
break;
}
else
{
nFirst = i;
}
}
umValueIndex[array[i]] = i;
}
}
if (twoIndex.unFirst < 0 || twoIndex.unSecond < 0)
{//遍历一遍,查找结果
for (auto iter = umValueIndex.begin(); iter != umValueIndex.end(); ++iter)
{
if (umValueIndex.find(nTarget - iter->first) != umValueIndex.end())
{
auto findIter = umValueIndex.find(nTarget - iter->first);
if(iter == findIter)
continue;//找到了自己,不符合
if (iter->second < findIter->second)
{
twoIndex.unFirst = iter->second;
twoIndex.unSecond = findIter->second;
}
else
{
twoIndex.unFirst = findIter->second;
twoIndex.unSecond = iter->second;
}
break;
}
}
}
return twoIndex;
}
int main()
{
int array[] = {1,1,2,5,-7,-9,0,45,6,3,7,5,5,10,78};
STwoIndex ti = GetArrayIndex(array, 15, 17);
}