数组元素的目标和
暴力解法:
#include<iostream>
using namespace std;
const int N = 100010;
int a[N], b[N];
int n, m, x;
pair<int, int> find(int x)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (a[i] + b[j] == x)
return { i,j };
}
}
return { -1,-1 };
}
int main()
{
cin >> n >> m >> x;
for (int i = 0; i < n; i++) cin >> a[i];
for (int j = 0; j < m; j++) cin >> b[j];
pair<int, int> end = find(x);
cout << end.first << " " << end.second << endl;
return 0;
}
时间复杂度:O(n*m)
由于本题有时间限制所以暴力过不了。
使用vector加上map解法:
#include<iostream>
#include<map>
#include<vector>
using namespace std;
vector<int> a;
map<int, int>b;
int n, m, x;
pair<int, int> find(int x)
{
for (int i = 0; i < n;i++)
{
auto it = b.find(x - a[i]);
if (it != b.end())
{
return { i,it->second };
}
}
return { -1,-1 };
}
int main()
{
cin >> n >> m >> x;
for (int i = 0; i < n; i++)
{
int temp;
cin >> temp;
a.push_back(temp);
}
for (int j = 0; j < m; j++)
{
int temp;
cin >> temp;
b.insert(make_pair(temp, j));
}
pair<int, int> end = find(x);
cout << end.first << " " << end.second << endl;
return 0;
}
运行时间:
时间复杂度:O(n*logm)
由于本题中主要的时间消耗是拿来查找b中是否存在与x-a[i]的值,所以可以使用unordered_map替代map
使用unordered_map后做法:
#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
vector<int> a;
unordered_map<int, int>b;
int n, m, x;
pair<int, int> find(int x)
{
for (int i = 0; i < n;i++)
{
auto it = b.find(x - a[i]);
if (it != b.end())
{
return { i,it->second };
}
}
return { -1,-1 };
}
int main()
{
cin >> n >> m >> x;
for (int i = 0; i < n; i++)
{
int temp;
cin >> temp;
a.push_back(temp);
}
for (int j = 0; j < m; j++)
{
int temp;
cin >> temp;
b.insert(make_pair(temp, j));//由于find查找的是key所以值放在前面
}
pair<int, int> end = find(x);
cout << end.first << " " << end.second << endl;
return 0;
}
运行时间:
时间复杂度:O(n) 但是由于unordered_map底层是哈希表,哈希表的构造速度慢
至于map和unordered_map区别可以看这篇文章【C++】学习笔记(十二)----set和unordered_set、map和unordered_map区别_深思沉浮的博客-CSDN博客
使用双指针做法:
#include<iostream>
using namespace std;
const int N = 100010;
int a[N], b[N];
int n, m, x;
pair<int, int> find(int x)
{
for (int i = 0, j = m - 1; i < n; i++);
{
while (j >= 0 && a[i] + b[j] > x) j--;
if (a[i] + b[j] == x) return { i,j };
}
return { -1,-1 };
}
int main()
{
cin >> n >> m >> x;
for (int i = 0; i < n; i++) cin >> a[i];
for (int j = 0; j < m; j++) cin >> b[j];
pair<int, int> end = find(x);
cout << end.first << " " << end.second << endl;
return 0;
}
运行时间:
时间复杂度:O(n+m)
总结:
本题目中由于给出的两组数据均为有序,所以使用双指针时间消耗比较小,但是双指针的使用限制比较大,数组必须存在单调性
以下是双指针模板借鉴:
for (int i = 0, j = 0; i < n; i ++ )
{
while (j < i && check(i, j)) j ++ ;//或者j--这样j初始时应该为最后一个元素
// 具体问题的逻辑
}