1. 程式人生 > >(四)王道機試指南___Hash的應用

(四)王道機試指南___Hash的應用

算例1

  • 題目描述

  • 解題思路

①方法一:用陣列將輸入資料儲存,遍歷查詢比較統計

②方法二:因輸入的分數控制在100以內且為整數,即種類有限,共101種可能,因此利用hash陣列對這101種可能分別計數即可

  • 解題程式碼

#include <stdio.h>
int main() {
	int n;
	while (scanf("%d", &n) != EOF && n != 0) { //輸入判斷增加對n是否等於零進行判斷
			int Hash[101] = { 0 }; //建立一個初始為0的Hash陣列用來記錄各種分數出現的次數
			for (int i = 1; i <= n;i++) {
				int x;
				scanf("%d", &x);
				Hash[x] ++; //統計分數出現次數
			}
		int x;
		scanf("%d", &x);
		printf("%d\n", Hash[x]); // 得到需要查詢的目標分數後,只需簡單的查詢我們統計的數量即可
	}
	return 0;
}
  • 注意點

①如此簡潔明瞭啊,事半功倍!

算例2

  • 題目描述

  • 解題思路

①這裡要思考複雜度問題,排序數量比較龐大1000000,即使使用快排(O(nlogn)),時間複雜度會達到千萬數量級,超出時間限制

②此題的輸入資料種類也是有限的,所以利用hash陣列求解,只需統計一遍+遍歷查詢一遍,時間複雜度在百萬數量級,滿足時間要求

  • 解題程式碼

#include <stdio.h>
#define OFFSET 500000 //偏移量,用於補償實際數字與陣列下標之間偏移
int Hash[1000001]; //Hash陣列,記錄每個數字是否出現,不出現為0,出現後被標記成1
int main() {
	int n, m;
	while (scanf("%d%d", &n, &m) != EOF) {
		for (int i = -500000; i <= 500000; i++) {
			Hash[i + OFFSET] = 0;
		} //初始化,將每個數字都標記為未出現
		for (int i = 1; i <= n;i++) {
			int x;
			scanf("%d", &x);
			Hash[x + OFFSET] = 1; //凡是出現過的數字,該陣列元素均被設定成1
		}
		for (int i = 500000; i >= -500000; i--) { //輸出前m個數
			if (Hash[i + OFFSET] == 1) { //若該數字在輸入中出現
				printf("%d", i); //輸出該數字
				m--; //輸出一個數字後,m減一,直至m變為0
				if (m != 0) printf(" "); //注意格式,若m個數未被輸出完畢,在輸出的數字後緊跟一個空格
				else {
					printf("\n"); //若m個數字已經被輸出完畢,則在輸出的數字後面緊跟一個換行, 並跳出遍歷迴圈
						break;
				}
			}
		}
	}
	return 0;
}
  • 注意點

①hash陣列寫main裡面會棧溢位!!

②int型資料範圍記一下:2147483647~-2147483648

③注意格式:最後一個數字輸出後不帶空格,這個是格式要求要扣分的!

④int型陣列賦值的時候,若int A[10]={0};則全部為0;若int A[10]={1};則只有第一個是1,其他是0;