九度OJ 1371 最小的K個數 堆排序

2022-07-27 23:09:18 字數 1489 閱讀 4086

題目描述:輸入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...