#剑指offer29最小的K个数
最小的K个数
https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&&tqId=11182&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
剑指offer29最小的K个数
1、普通排序和堆排序
普通排序--直接vector用sort,时间复杂度O(nlog(n)),空间复杂度O(1)
堆排序
(1)multiset或者set
Class Person { public: String name; int age; Perosn(String name1,int age1):name(name1),age(age1){} } Class cmp //仿函数 { public: bool operator()(const Person &p1,const Person &p2) const { return p1.age<p2.age; } } set<int>s; //默认升序 set<int,less<int>>s;//升序,等同默认 set<int,greater<int>>s;//降序: set<Person,cmp>s;//自定义类型,cmp为仿函数
(2)multimap或者map
map<T1,T2> m;//参数1:key值,参数2:value值,默认按照key的升序排列元素 map<T1,T2,less<T1> > m; //升序,等同上 map<T1,T2,greater<T1>> m; //该容器是按key的降序排列元素 map<Person,Person,cmp> m; //自定义类型,写仿函数,其实此时map也可以不写仿函数,如下用 map<int,Person>m; //直接用插入元素的age作为键值 Person p1("Lee",30); m.insert(pair<int,Person>(p1.age,p1)); //直接用age作为键值排序
(3)priority_queue
priority_queue<int>q; //默认大顶堆 priority_queue<int,vector<int>,less<int>>q;//大顶堆,等同默认 priority_queue<int,vector<int>,greater<int>>q;//小顶堆:
class Solution { public: #define Ator multiset<int>::iterator vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int>v; multiset<int>s;//默认升序,即multiset<int,less<int>>,降序multiset<int,greater<int>> if(k>input.size()) return v; for(int x:input) s.insert(x); int index=0; for(Ator it=s.begin();it!=s.end()&&index<k;it++,index++) //复制前k个数到v v.push_back(*it); return v; } };
2、快排简化此题
class Solution { public: int partition(vector<int> &input,int l,int r) //排序数组[l,r]之间元素 { int key=input[r]; //选择基准 int index=l; //index最终会表示基准的正确位置,index之前[l,index)小于key,index之后(index,r]大于key for(int i=l;i<r;i++) {//循环未完成之前,index位置元素始终会是大于key的元素,因为小于key的会使得index++,置于index之前 if(input[i]<key)//如果小于基准,与index元素交换,index位置后移,使得小于基准元素至于index之前 { swap(input[i],input[index]); ++index; } } swap(input[index],input[r]); return index; } vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int>v; if(input.empty()||k>input.size()||k<0) return v; //若得出快速排序中某个标准的位置index=k或者index=k-1都可以轻易前k个小的数[0----index-1]或者[0---index] //二分思想 int l=0; int r=input.size()-1; while(l<=r) { int index=partition(input,l,r); if(index==k||index==k-1) //前k个元素都能确定 return vector<int>(input.begin(),input.begin()+k);//匿名对象,拷贝构造,不包括末尾的左闭右开 else if(index>k) //大了 { r=index-1; } else if(index<(k-1)) { l=index+1; } } return v; } };