雜湊中用空間換時間
阿新 • • 發佈:2021-01-22
這篇是讀胡凡的《演算法筆記》摘抄的。
雜湊(hash)是常用的演算法思想之一,在很多程式中都會有意無意地使用到。
先來看一個簡單的問題:給出N個正整數,再給出M個正整數,問這M個數中的每個數分別是否在N個數中出現過,其中N,M≤105,且所有正整數均不超過105.例如N=5, M=3,N個正整數為{8,3,7,6,2},欲查詢的M個正整數為{7,4,2},於是後者中只有7和2在N個正整數中出現過,而4是沒有出現過的。
對這個問題,最直觀的思路是:對每個欲查詢的正整數x,遍歷所有N個數,看是否有一個數與x相等。這種做法的時間複雜度為O(NM),當N和M都很大(105級別)時,顯然是無法承受的。
#include<cstdio>
const int maxmn = 100001;
bool hashtable[maxmn] = {false};
int main(){
int N,M,x;
scanf("%d%d",&N,&M); //輸入的時中間加個空格就表示是前一個整數輸入結束
for(int i = 0;i<N;i++)
{
scanf("%d",&x);
hashtable[x] = true;
}
for(int i = 0;i<M;i++)
{
scanf("%d",&x);
if(hashtable[x] == true)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}
同樣的,如果題目要求M個欲查詢的數中每個數在N個數中出現的次數,那麼可以把hashTable陣列替換為int型,然後在輸入N個數時進行預處理,即當輸入的數為x時,就令hashTable[x]++,這樣就可以用O(N+M)的時間複雜度
#include<cstdio>
const int maxmn = 100001;
int hashtable0[maxmn] = {0};
int main()
{
int N,M,x;
scanf("%d%d",&N,&M);
for(int i = 0;i<N;i++)
{
scanf("%d",&x);
hashtable0[x]++;
}
for(int i = 0;i<M;i++){
scanf("%d",&x);
printf("%d次\n",hashtable0[x]);
}
}