面試中被問到一組有序序列(從小到大),求這組序列中的前n個

qq_23923713發表於2020-10-05

之前面試的時候,被問到,我的回答是每次都取頭部進行比較,然後再取剩下的進行比較。身為菜雞的我思路有了,卻寫不出來,後面想一想,這種topk問題,不就是堆問題解決嗎?唉。菜雞的悲哀。

如果是一個數列,求前n個如下

#include<iostream>
#include<queue>
#include<vector>

//求一組數中最小的n個數   
using namespace std;


class Solution {
public:
	//獲取陣列中第n個小的數
	vector <int> Get_min_k(vector<int> v,int k)
	{
		//對於sort()函式,傳入的第三個引數如果是greater<int>(),則為降序;
		//對於priority_queue,傳入的第三個引數如果是greater<int>,為小頂堆
		priority_queue<int, vector<int>, greater<int> > q;
		vector <int> ret;
		for (int i = 0;i < k;i++)
		{
			if (q.size()<=k)
			{
				q.push(v[i]);
			}
			else
			{
				if (v[i]< q.top())//小的話放進去
				{
					q.pop();
					q.push(v[i]);
				}

			 }
		
		}
		int i = 1;

		while (!q.empty())
		{
			ret.emplace_back(q.top())  ;
			q.pop();
			i++;
		}
		return ret;
	}
};

int main()
{
	vector<int> v{5,3,6,8,1,2,3,56,23,65,3,6};
	Solution s;
	vector<int> ret=s.Get_min_k(v,5);
	int i = 1;
	for (auto it = ret.begin();it!= ret.end();it++)
	{
		cout << "第" << i +1<< "個元素為" << *it << endl;
	}
		
	
}

後來想了想,多組,數列時,我們只要將多組中的前n個放到優先佇列(堆)中即可,不需要都放進去;程式碼如下

	vector <int> Get_min_k2(vector<vector<int>> vv, int k)
	{
		priority_queue<int, vector<int>, greater<int> > q;
		vector <int> ret;
		for (int i = 0;i < vv.size();i++)
		{
			for (int j=0;j< vv[i].size()&&j<k;j++)
			{
				if (q.size() <= k)
				{
					q.push(vv[i][j]);
				}
				if (vv[i][j] < q.top())//小的話放進去
					{
						q.pop();
						q.push(vv[i][j]);
					}
			}
			

		}
		int i = 1;

		while (!q.empty())
		{
			ret.emplace_back(q.top());
			q.pop();
			i++;
		}
		return ret;

	}

2020.10.5

相關文章