簡介:
哈希表又稱爲散列表,是實現字典操作的一種有效的數據結構。通過哈希函數將關鍵字映射到表中的某個位置上進行存放,以實現快速插入和查詢的。時間複雜度可達到O(n).
爲什麼要用到哈希:比如說有n(1<=n<=1e6)個數,當給你一個非常大的數時,爲了方便查找這個數是否出現過,我們可以給這個數重新編號到1~n,這樣我們就可以快速的找到想要的答案。
題目描述
維護一個集合,支持如下幾種操作:
“I x”,插入一個數x;
“Q x”,詢問數x是否在集合中出現過;
現在要進行N次操作,對於每個詢問操作輸出對應的結果。
輸入格式
第一行包含整數N,表示操作數量。
接下來N行,每行包含一個操作指令,操作指令爲”I x”,”Q x”中的一種。
輸出格式
對於每個詢問指令“Q x”,輸出一個詢問結果,如果x在集合中出現過,則輸出“Yes”,否則輸出“No”。每個結果佔一行。
數據範圍
1≤N≤105
−109≤x≤109
輸入樣例:
5
I 1
I 2
I 3
Q 2
Q 5
輸出樣例:
Yes
No
題解:
拉鍊法:
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e6 + 10, mod = 100003;
int h[N], e[N], ne[N], idx = 1;
void insert(int x)
{
int k = (x % mod + mod) % mod;
e[idx] = x, ne[idx] = h[k], h[k] = idx++;
}
bool Find(int x)
{
int k = (x % mod + mod) % mod;
for(int i = h[k]; i != -1; i = ne[i])
if(e[i] == x)return true;
return false;
}
int main()
{
int n, x;
string s;
memset(h, -1, sizeof h);
cin >> n;
while(n--){
cin >> s >>x;
if(s == "I"){
insert(x);
}
else {
if(Find(x))cout << "Yes" << endl;
else cout << "No" << endl;
}
}
return 0;
}
開放尋址法:
#include<iostream>
#include<cstring>
using namespace std;
const int N = 200003, Max = 0x3f3f3f3f;
int h[N];
int Find(int x)
{
int k = (x % N + N) % N;
while(h[k] != Max && h[k] != x){
k++;
if(k == N)k = 0;
}
return k;
}
int main()
{
int n, x;
string s;
cin >> n;
memset(h, Max, sizeof h);
while(n--){
cin >> s >> x;
if(s == "I"){
int k = Find(x);
h[k] = x;
}
else {
int k = Find(x);
if(h[k] != Max)cout << "Yes" << endl;
else cout << "No" << endl;
}
}
return 0;
}