題目描述:輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
輸入:每個測試案例包括2行:
第一行為2個整數n,k(1<=n,k<=200000),表示陣列的長度。
第二行包含n個整數,表示這n個數,陣列中的數的範圍是[0,1000 000 000]。
輸出:對應每個測試案例,輸出最小的k個數,並按從小到大順序列印。
樣例輸入:
8 4
4 5 1 6 2 7 3 8
樣例輸出:
1 2 3 4
我們可以先建立乙個大小為k的資料容器來儲存最小的k個數字。接下來我們每次從輸入的n個整數中讀入乙個數。如果容器中已有的數字少於k個,則直接把這次讀入的整數放入容器之中;如果容器中已有k個數字了,也就是容器已滿,此時我們不能再插入新的數字而只能替換已有的數字。我們找出這已有的k個數中最大值,然和拿這次待插入的整數和這個最大值進行比較。如果待插入的值比當前已有的最大值小,則用這個數替換替換當前已有的最大值;如果帶插入的值比當前已有的最大值還要大,那麼這個數不可能是最小的k個整數之一,因為我們容器內已經有k個數字比它小了,於是我們可以拋棄這個整數。
因此當容器滿了之後,我們要做三件事情:一是在k個整數中找到最大數,二是有可能在這個容器中刪除最大數,三是可能要插入乙個新的數字,並保證k個整數依然是排序的。如果我們用乙個二叉樹來實現這個資料容器,那麼我們能在o(logk)時間內實現這三步操作。因此對於n個輸入數字而言,總的時間效率就是o(nlogk)
下面是用堆排序解決該問題的**:
#include void heapsort(int array, int len);void buildmaxheap(int array, int len);
void shiftdown(int array, int index, int len);
void swap(int *m, int *n);
int main(void)
}heapsort(array, k);
for (i=1; i<=k; ++i)
putchar ('\n');
}return 0;}
void heapsort(int array, int len)
}void shiftdown(int array, int index, int len)
else
}else
break;
}else
else
break;
}}}
void swap(int *m, int *n)
清橙oj上相似的題目:
九度oj上相似的題目:
參考資料:何海濤 -- 程式設計師面試題精選100題(05)-查詢最小的k個元素[演算法]
九度oj 1371 最小的k個數
時間限制 1 秒 記憶體限制 32 兆 特殊判題 否 提交 6191 解決 1309 題目描述 輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,輸入 每個測試案例包括2行 第一行為2個整數n,k 1 n,k 200000 表示陣...
九度 題目1371 最小的K個數
時間限制 1 秒 記憶體限制 32 兆 特殊判題 否 提交 4133 解決 856 題目描述 輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,輸入 每個測試案例包括2行 第一行為2個整數n,k 1 n,k 200000 表示陣列...
九度OJ 1087 約數的個數
題目1087 約數的個數 時間限制 1 秒 記憶體限制 32 兆 特殊判題 否 提交 6056 解決 1838 題目描述 輸入n個整數,依次輸出每個數的約數的個數 輸入 輸入的第一行為n,即陣列的個數 n 1000 接下來的1行包括n個整數,其中每個數的範圍為 1 num 1000000000 當n...