题目
这个问题的最基本形式是这样:给你一个数组和一个整数target,可以保证数组中存在两个数的和为target,请你返回这两个数的索引。
比如输入nums = [3,1,3,6],target = 6,算法应该返回数组[0,2],因为 3 + 3 = 6。
这个问题如何解决呢?首先最简单粗暴的办法当然是穷举了,这个解法非常直接,时间复杂度 O(N^2),空间复杂度 O(1)。
更好一点的解法,可以通过一个哈希表减少时间复杂度。
这样,由于哈希表的查询时间为 O(1),算法的时间复杂度降低到 O(N),但是需要 O(N) 的空间复杂度来存储哈希表。不过综合来看,是要比暴力解法高效的。
代码
实现代码如下:
#include <iostream>
#include <map>
using namespace std;
// 简单的暴力搜索
bool two_sum(int* array, int len, int target, int* i, int* j) {
for (int x = 0; x < len; x++)
for (int y = x + 1; y < len; y++)
if (array[x] + array[y] == target) {
*i = x;
*j = y;
return true;
}
return false;
}
// hashMap
bool hash_TwoSum(int* array, int len, int target, int* i, int* j) {
map<int, int>index;
map<int, int>::iterator it;
for (int x = 0; x < len; x++)
index[array[x]] = x;
for (int x = 0; x < len; x++) {
int other = target - array[x];
it = index.find(other);
if (it!= index.end() && it!= index.find(array[x])) {
*i = x;
*j = it->second;
return true;
}
}
return false;
}
int main() {
int nums[] = { 3,1,3,6 }, target = 7;
int i, j,len=end(nums)-begin(nums);
if (two_sum(nums, len, target, &i, &j))
cout << i << " " << j << endl;
if (hash_TwoSum(nums, len, target, &i, &j))
cout << i << " " << j << endl;
else cout << "Not exist!";
system("pause");
return 0;
}