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

找前n個最大數

假設有10000個數,需要找到裏面前10個最大數。
樸素的解法當然是先排序,然後輸出前10 個數,時間複雜度最低爲O(logn)。
思考我們可以維護一個10個元素大小的容器,用在某種算法使得這個容器裏面維護的就是我們需要的10個數。
先從vector開始思考,用前10和數初始化,然後不斷的遍歷剩餘元素,找到一種條件使得可以將新遍歷得到的數字加入到vector中,爲使得vector保存的是前10個最大的元素,則如果某一次遍歷得到的元素大於vector中最小元素,則可以將該元素與vector中的最小元素做替換。爲了達成這一目的,我們需要維護一個vector最小元素的變量,並需要在發生替換時進行更新。
vector雖然可以滿足這一想法的實現,但並不是十分的高效,既然我們每一次都需要將容器中的最小元素和另一個元素交換,不如用小頂堆來實現,最小元素必在堆頂,比較和替換都很容易。

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<functional>

using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int> vec{ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
	priority_queue<int, vector<int>, greater<int>> pq(vec.begin(), vec.begin() + n);
	for (int i = n; i < vec.size(); i++)
	{
		if (vec[i] > pq.top())
		{
			pq.push(vec[i]);
			pq.pop();
		}
	}
	while (!pq.empty())
	{
		cout << pq.top() << " ";
		pq.pop();
	}
	return 0;
}

生成100個不重複的隨機數

簡單思路,不斷的取隨機數,已存在結果集合內則跳過,否則加入結果數組,需要用到哈希表來節省時間,而且效率很低。
既然要求不重複,我們不妨直接先生成100個不同的數字,存放在集合vec中,然後找到一種思路從vec中取數字加入如果數組res,直接思路可以不斷的生成隨機數,以該數爲索引從vec中取數,若該數已經取走,則跳過,這樣還是效率不高。因此我們思考一種每一次都要取到數的方法,將每次生成的隨機數取模vec的大小,每次取數之後都將取到的數從vec中刪除。

#include<iostream>
#include<vector>
#include<algorithm>
#include<random>
#include<ctime>

using namespace std;

int main() {
	vector<int> vec(100), res;
	for (int i = 0; i < 100; i++)
		vec[i] = i;
	/*default_random_engine rengine;
	uniform_int_distribution<int> dist;*/
	int n = 100;
	while (n)
	{
		//int curr = dist(rengine) % n;
		srand(int(time(0)));
		int curr = rand() % n;
		res.push_back(vec[curr]);
		vec.erase(vec.begin() + curr);
		n--;
	}
	for (auto &a : res)
		cout << a << " ";
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章