1. 程式人生 > 其它 >雜湊中用空間換時間

雜湊中用空間換時間

技術標籤:演算法c語言

這篇是讀胡凡的《演算法筆記》摘抄的。

雜湊(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級別)時,顯然是無法承受的。

那麼該如何做呢?—不妨用空間換時間,即設定一個bool型陣列 hashTable[1000],其中 hashTable[x]=tmue表示正整數x在N個正整數中出現過,而 hashTable[x]= false表示正整數x在N個正整數中沒有出現過。這樣就可以在一開始讀入N個正整數時就進行預處理,

#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]);
	}
}