题目描述
给定一个数组arr,给定一个整数sum,寻找数组中是否存在两个数a1,a2,使得a1 + a2 == sum.
题目解析
以下是几种最容易想到的解决方式:
- 暴力求解
void TwoSum(int *arr,int *result,int len,int sum)
{
for(int i = 0;i<len;++i)
{
for(int j = i+1;j<len;++j)
{
if(arr[i]+arr[j] == sum)
{
result[0] = i;
result[1] = j;
return;
}
}
}
}
- 排序 + 双指针: 前提是数组元素顺序允许改变
如果数组是无序的,先将数组进行排序,时间复杂度大约为0(NlogN),然后使用双指针,从两头开始遍历:
假设初始值i = 0,j = n - 1
如果arr[i] + arr[j] < sum,那么 i++
如果arr[i] + arr[j] > sum,那么 j–
如果arr[i] + arr[j] == sum,那么将下标i和j返回回去
void TwoSum2(int *arr,int *result,int len,int sum)
{
int i = 0;
int j = len -1;
while(i < j)
{
if(arr[i] + arr[j] > sum)
{
j--;
}
else if(arr[i] + arr[j] < sum)
{
i++;
}
else
{
result[0] = i;
result[1] = j;
return;
}
}
}
- 利用哈希表解决:
先将数组中的所有值散列到一个哈希表中,然后遍历数组,每次取一个值arr[i],找哈希表中是否存在一个值sum - arr[i],但是需要注意一点的是,假设数组arr = {1,2,2,7},sum = 4,那么我们找sum - arr[1]时,需要看哈希链表上有几个2,如果有2个2,那么就找到了,如果只有一个2,那么就是arr[1]本身,需要继续遍历的找。
void TwoSum(int *arr,int len,int target,int *result)
{
//val : index
std::unordered_map<int,int> count_;
for(int i = 0; i < len;++i)
{
auto it = count_.find(target - arr[i]);
if(it != count_.end())
{
result[0] = i;
result[1] = it->second;
return;
}
count_.insert({arr[i],i});
}
}