假設有10000個數,需要找到裡面前10個最大數。
樸素的解法當然是先排序,然後輸出前10 個數,時間複雜度最低為o(logn)。
思考我們可以維護乙個10個元素大小的容器,用在某種演算法使得這個容器裡面維護的就是我們需要的10個數。
先從vector開始思考,用前10和數初始化,然後不斷的遍歷剩餘元素,找到一種條件使得可以將新遍歷得到的數字加入到vector中,為使得vector儲存的是前10個最大的元素,則如果某一次遍歷得到的元素大於vector中最小元素,則可以將該元素與vector中的最小元素做替換。為了達成這一目的,我們需要維護乙個vector最小元素的變數,並需要在發生替換時進行更新。
vector雖然可以滿足這一想法的實現,但並不是十分的高效,既然我們每一次都需要將容器中的最小元素和另乙個元素交換,不如用小頂堆來實現,最小元素必在堆頂,比較和替換都很容易。
簡單思路,不斷的取隨機數,已存在結果集合內則跳過,否則加入結果陣列,需要用到雜湊表來節省時間,而且效率很低。#include
#include
#include
#include
#include
using
namespace std;
intmain()
; priority_queue<
int, vector<
int>
, greater<
int>>
pq(vec.
begin()
, vec.
begin()
+ n)
;for
(int i = n; i < vec.
size()
; i++)}
while
(!pq.
empty()
)return0;
}
既然要求不重複,我們不妨直接先生成100個不同的數字,存放在集合vec中,然後找到一種思路從vec中取數字加入如果陣列res,直接思路可以不斷的生成隨機數,以該數為索引從vec中取數,若該數已經取走,則跳過,這樣還是效率不高。因此我們思考一種每一次都要取到數的方法,將每次生成的隨機數取模vec的大小,每次取數之後都將取到的數從vec中刪除。
#include
#include
#include
#include
#include
using
namespace std;
intmain()
for(
auto
&a : res)
cout << a <<
" ";
return0;
}
演算法 通過堆排序,獲取前N個最大數
在一組無序陣列中,比如 1,9,8,2,7,3,6,4,5 將陣列看做是乙個堆,也可以用二叉樹來表示 但是這個堆現在還不是大頂堆,大頂堆的特點是父節點永遠大於左右子節點 第一步需要將這個堆構建成大頂堆 構建前需要知道的幾點 構建大頂堆 param array 原始陣列 param length 需要...
快速排序以及基於快排思想的找前k個最大數
1 int partition vector v,int head,int rear 7swap v head v rear 8while v head key head 11swap v rear v head 1213 14 v head key 15 my count 16return hea...
堆排序查詢前N個最大數和二分查詢演算法
先了解堆排序概念 堆排序利用了大根堆 或小根堆 堆頂記錄的關鍵字最大 或最小 這一特徵,使得在當前無序區中選取最大 或最小 關鍵字的記錄變得簡單。1 用大根堆排序的基本思想 先將初始檔案r 1.n 建成乙個大根堆,此堆為初始的無序區 再將關鍵字最大的記錄r 1 即堆頂 和無序區的最後乙個記錄r n ...