题目:
输入n个正整数,找出其中最小的k个数。例如:输入 1 3 5 7 9 8 2 其中 最小的3个数字是 1 2 3
思路1:
就像前面的快排一样 , 那我们可以找到前k个最小的数字(但是不保证最小数字是有序的)
code1:
int partation(int* numbers, int length, int begin, int end)
{
if (begin < end)
{
int left = begin;
int right = end;
int key = numbers[left];
while (left != right)
{
while (left < right && numbers[left] <= key)
left++;
while (left < right && numbers[right] >= key)
right--;
if (left < right)
std::swap(numbers[left], numbers[right]);
}
if (left != begin)
std::swap(numbers[left], numbers[begin]);
return left;
}
return -1;
}
<span style="color:#ff0000;">void GetLeastNumbers(int* inputs, int n, int* outputs, int k)</span>
{
if (inputs == NULL || outputs == NULL)
return;
int begin = 0;
int end = n - 1;
int index = partation(inputs, n, begin, end);
while (index != k-1) // 找k前面的数字
{
if (index > k-1) //比k大
{
end = index - 1;
index = partation(inputs, n, begin, end);
}
else
{
begin = index + 1;
index = partation(inputs, n, begin, end);
}
}
for (int i = 0; i < k; ++i)
{
outputs[i] = inputs[i];
}
}
思路2:
我们可以创建一个大小为K的数据容器用来存放最小的k个数字。在插入数据的时候,如果插入数据与容器内最大的数据还小,那么要插入的数据替换容器中最大的数据;同理,如果比容器内最大值还大那么久不需要插入数据。
总结下我们需要做的事:1、在k个数据中找到最大的数据 ;2、有可能删除容器的最大数;3、插入新的数据
那么,我们很容易就想到了 最大堆 , 但是短时间实现一个最大堆还是挺难的,那么我们考虑使用STL
code:
void GetLeastNumbers_2(const std::vector<int>&data, std::set<int>& leastNum, int k)
{
leastNum.clear();
if (k < 1 || data.size() < k)
return;
vector<int>::const_iterator it = data.begin();
for (; it != data.end(); ++it)
{
if (leastNum.size() < k)
leastNum.insert(*it);
else
{
if (*it < *(leastNum.begin()))
{
leastNum.erase(leastNum.begin());
leastNum.insert(*it);
}
}
}
}