Hash 的應用
@(算法)
注:本文所討論的Hash
只講訴其在機試試題解答中的應用。
題目描述:
給你n個整數,請按從大到小的順序輸出其中前m大的數
輸入:
每組測試數據有兩行,第一行有兩個數n,m(0<n,m<1000000),第二行包含n個各不相同,且都處於區間[-500000,500000]的整數
輸出:
對每組測試數據按從大到小的順序輸出前m大的數
我們很容易會想到,用sort()
函數將其降序排序,然後輸出前m大的數。
多麼簡單的一道題啊,不禁讓我感到疑惑,是否忽略了什麼?
在本題中,如果使用快排來解決該題,由於待排數字的數量十分龐大(1000000),根據快排的時間複雜度O(nlogn)
,其時間複雜度將會達到千萬級。所以,我們並不能使用快速排序來解決本題。
代碼塊
#define OFFSET 500000
int hash[1000000];
int main() {
int n, m;
while (scanf("%d%d",&n,&m)!=EOF &&n!=0)
{
for (int i = -500000; i <= 500000; i++)
{
hash[i + OFFSET] = 0;
}
for (int i = 0; i < n; i++) {
int x;
scanf("%d", &x);
hash[x + OFFSET]=1;
}
for (int i = 1000000; i >= m+OFFSET; i--)
{
if (hash[i]==1)
{
printf("%d ", i - OFFSET);
}
}
}
return 0;
}
代碼解讀#define OFFSET 500000
由於輸入數據出現負數,於是我們不能直接把輸入數據當做數組下標來訪問數組元素,而是將每一個輸入的數組都加上一個固定的偏移量,使輸入數據的
[-500000,500000]區間被映射到數組下標的[0,1000000]區間。
無疑,這是一種在時間上更加高效的排序方法。
參考資料: