关键词:排序 快排思想 计数排序 大顶堆
题目:库存管理 III
方法一:sort快排,这种方法绝对过不了面试
方法二:快排思想,只排一半。效率最高
方法三:维护一个大小为cnt的最大堆
方法四:计数排序。
方法一:
sort快排
思路:
先sort快排,然后取前cnt
复杂度计算:
时间复杂度O(nlogn)
空间复杂度O(N)
代码:
class Solution {
public:vector<int> inventoryManagement(vector<int>& stock, int cnt) {sort(stock.begin(),stock.end());vector<int> res(stock.begin(),stock.begin()+cnt);return res;}
};
方法二:效率最高
快排思想
思路:
快排会把大于target的数放在左边,把小于target的数放在右边,所以如果target排好之后,target的索引i刚好等于cnt即可。
来自k神的图:
如果cnt刚好等于2,那么返回前面1 0即可。
如果i大于cnt,那么说明我们还要排一排左边的数。
如果i小于cnt,那么说明我们还要排一排右边的数。
复杂度计算:
时间复杂度O(N)
空间复杂度O(logN)
代码:
class Solution {
public:vector<int> inventoryManagement(vector<int>& stock, int cnt) {quick_sort(0,stock.size()-1,stock,cnt);return vector<int>(stock.begin(),stock.begin()+cnt);}void quick_sort(int p_l,int p_r,vector<int>& stock,int cnt){int l=p_l,r=p_r;if(l>=r) return;int target=stock[l];while(true){while(stock[r]>=target&&l<r){r--;}stock[l]=stock[r];while(stock[l]<=target&&l<r){l++;}stock[r]=stock[l];if(l==r) {stock[l]=target;break;}}if(l==cnt) return;//排好了if(l<cnt)//排少了quick_sort(l+1,p_r,stock,cnt);if(l>cnt)//排多了quick_sort(p_l,l-1,stock,cnt);}
};
方法三:
维护一个大小为cnt的大顶堆。
思路:
维护一个大小为cnt的大顶堆q。
1、先往q里面塞cnt个数。
2、后面的数x先和堆顶q.top()比较:如果x>=q.top(),直接舍弃。
如果x<q.top(),先把堆顶推出q.pop(),然后再添加x。
3、输出大顶堆。
复杂度计算:
时间复杂度O(nlogk) k是前k小,因为维护的是k大小的大顶堆
空间复杂度O(k)
代码:
class Solution {
public:vector<int> inventoryManagement(vector<int>& stock, int cnt) {vector<int> result;if(cnt==0) return result;priority_queue<int,vector<int>,less<int>> Q;for(int i=0;i<cnt;++i){Q.push(stock[i]);}for(int i=cnt;i<stock.size();i++){if(Q.top()<=stock[i]) continue;Q.pop();Q.push(stock[i]);}for(int i=0;i<cnt;++i){result.push_back(Q.top());Q.pop();}return result;}
};
方法四:
计数排序
思路:
先计数排序,然后取前cnt。
复杂度计算:
时间复杂度O(n)
空间复杂度O(10000)
代码:
class Solution {
public:vector<int> inventoryManagement(vector<int>& stock, int cnt) {//计数排序//统计//累加//从后往前排vector<int> sort_result(stock.size(),0);vector<int> count_sort(10001,0);for(const int&x:stock){count_sort[x]++;}for(int i=1;i<count_sort.size();++i){count_sort[i]+=count_sort[i-1];}for(int i=count_sort.size()-1;i>=0;--i){while((i==0&&count_sort[i]!=0)||(i!=0&&count_sort[i]!=count_sort[i-1])){sort_result[count_sort[i]-1]=i;count_sort[i]--;}}return vector<int>(sort_result.begin(),sort_result.begin()+cnt);}
};