找前n個最大數 生成100個不重複的隨機數

2021-10-06 00:28:05 字數 1362 閱讀 7713

假設有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 ...