题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
考察点:时间复杂度分析;快速排序的灵活运用;特殊的数据结构使用。
思路1:时间复杂度为O(n)的算法,当我们可以修改输入的数组时。基于数组中的第K个数来调整,比k个数字小的都在左边
比k个数字大的都在右边。这样调整过后,就可以得到前k的元素。
class Solution {
public:
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
int Partition(vector<int>&input, int begin, int end)//数组中变化的一定加引用。
{
if (input.empty())
return 0;
int pivot = input[begin];//设置初始基准
while (begin < end)
{
while (begin < end && input[end] >= pivot)//从右侧找到一个不符合的准备交换
end--;
swap(input[begin], input[end]);
while (begin < end && input[begin] <= pivot)//从左侧找到一个不符合的准备交换
begin++;
swap(input[begin], input[end]);
}
return begin;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> result;
if (input.size() < k || k <= 0 || input.empty())
return result;
int start = 0;
int length = input.size();
int end = length - 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);
}
}
for (int i = 0; i < k; i++) //提取前k个元素
{
result.push_back(input[i]);
}
return result;
}
};
思路2:利用特殊的容器,这里采用multiset存放数据。
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
{
vector<int> result;
multiset<int, greater<int>> leastNumbers;//初始化set
multiset<int, greater<int>>::iterator setIterator;//初始迭代器
if (k < 1 || input.size() < k)
return result;
for (vector<int>::iterator it = input.begin(); it != input.end(); it++)//开始遍历vector
{
if (leastNumbers.size() < k)
leastNumbers.insert(*it);
else
{
setIterator= leastNumbers.begin();
if (*it < *(leastNumbers.begin())) //如果存在比set中最大值小的数据,就插入替换
{
leastNumbers.erase(setIterator);
leastNumbers.insert(*it);
}
}
}
for (setIterator = leastNumbers.begin(); setIterator != leastNumbers.end(); setIterator++)//数据转换
{
result.push_back(*setIterator);
}
return result;
}
};