题目描述
给定一个严格递增序列A和一个正整数k,在序列A中寻找不同的下标i、j,使得Ai+Aj=k。问有多少对(i,j)同时i<j满足条件。
注:使用hash法实现
输入描述
第一行两个正整数n、k(2≤n≤105、1≤k≤106),分别表示序列中的元素个数、给定的和;
第二行按顺序给出n个递增的正整数,表示序列A中的元素(1≤每个元素≤106)
输出描述
一个整数,表示满足条件的(i,j)且i<j的对数。
样例1
输入
5 6 1 2 4 5 6输出
2解释
1 + 5 = 6、2 + 4 = 6,因此有两对
题解 (哈希表)
#include<bits/stdc++.h>
using namespace std;
const int MAXK = 1000001;
int main(){
int n, k;
cin>>n>>k;
vector<int> v(n);
vector<bool> hash_table(MAXK, false);
for(int i=0;i<n;i++){
cin>>v[i];
hash_table[v[i]] = true;
}
int cnt = 0;
for(int i=0;i<n;i++){
if(hash_table[k - v[i]] && v[i] != k - v[i]){
cnt++;
hash_table[v[i]] = false;
}
}
cout<<cnt;
return 0;
}
题解 (双指针)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
vector<int> a(n);
// 输入序列
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int left = 0; // 左指针
int right = n - 1; // 右指针
int cnt = 0; // 满足条件的数对数量
// 双指针法
while (left < right) {
int sum = a[left] + a[right];
if (sum == k) {
cnt++; // 找到一对满足条件的数对
left++; // 移动左指针
right--; // 移动右指针
} else if (sum < k) {
left++; // 和太小,移动左指针
} else {
right--; // 和太大,移动右指针
}
}
cout << cnt;
return 0;
}