题目
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路一
基于partition,当 index正好为k的时候,就是第k大的数。时间复杂度O(n)
缺点:需要改变数组
class Solution { public: int Partition(vector<int>& input, int begin, int end) { int low = begin, high = end; int pivot = input[low]; while(low < high) { while( low < high && pivot<=input[high]) { high--; } input[low] = input[high]; while(low < high && pivot >= input[low]) { low++; } input[high] = input[low]; } input[low] = pivot; return low; } vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { int len=input.size(); if(len == 0 || k > len || k <= 0) return vector<int>(); if(len == k) return input; int start = 0, end = len - 1; int index = Partition(input,start,end); while(index != k - 1) { if (index > k - 1) { end = index-1; index = Partition(input,start,end); } else { start = index+1; index = Partition(input,start,end); } } vector<int> res(input.begin(), input.begin() + k); return res; } };
思路二
使用最大堆,存储最小的k个数字,时间复杂度为O(nlogk)。
当插入时,若该元素比容器中最大元素小,则把该元素放入。
优点:不需要更改数组,适合海量数据
class Solution { public: vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int> result; int len = input.size(); if(input.empty() || k <= 0 || len < k) return result; multiset<int, greater<int>> leastNumbers; // 从大到小排序 multiset<int, greater<int>>::iterator iterGreater; // 定义迭代器 vector<int>::iterator iter = input.begin(); for(; iter != input.end(); ++iter) { // 将前k个数直接插入进multiset中,注意是小于K if (leastNumbers.size() < k) leastNumbers.insert(*iter); else { // 因为设置的从大到小排序,故multiset中第一个位置的元素即为最大值 iterGreater = leastNumbers.begin(); // 如果input中当前元素比multiset中最大元素小,则替换;即保持multiset中这k个元素是最小的。 if(*iter < *(leastNumbers.begin())) { // 替换掉当前最大值 leastNumbers.erase(iterGreater); leastNumbers.insert(*iter); } } } for(iterGreater = leastNumbers.begin(); iterGreater!=leastNumbers.end(); ++iterGreater) result.push_back(*iterGreater); // 将multiset中这k个元素输出 return result; } };
原文地址:https://www.cnblogs.com/shiganquan/p/9344759.html
时间: 2024-11-08 06:54:46