方法一 基于堆排序
构建小顶堆arr[0:n-1]后,重复k次:
将堆顶交换到堆末,即swap(arr[0], arr[n-1]),调整arr[0:n-2],使其为小顶堆。
arr[n-1:n-k]即为所求
方法二 基于快排
对于arr[beg:end]每次递归调整后,基准元素arr[j]不小于前面的元素,不大于后面的元素
如果j >= k, 说明j后面的元素不可能是前k个最小元素,无需对j后的元素arr[j+1:end]进行递归排序,只需要对j前的元素arr[beg:j-1]进行递归排序。这是与快排的唯一区别,用于提高效率。
如果j < k, 说明j前的元素包含在前k个最小元素,除了对j前的元素进行递归排序外,还需要对j后面的元素进行递归排序。
两种方法都实现一下:
//基于快排
class Solution {
public:
int adjust(vector<int> &a, int beg, int end)
{
int i = beg + 1, j = end;
int base = a[beg];
while (i <= j)
{
while (a[i] <= base && i <= j)
{
i++;
}
while (a[j] >= base && j >= i)
{
j--;
}
if (i < j)
{
swap(a[i], a[j]);
i++;
j--;
}
}
//循环完后i和i之后的元素都比base大 ,
//j和j之前的元素都比base小
swap(a[beg], a[j]);
return j;
}
void qSort(vector<int> &vec, int k, int beg, int end)
{
if (beg >= end)
{
return;
}
int loc = adjust(vec, beg, end);
if (loc > k - 1)
{
qSort(vec, k, beg, loc - 1);
}
else
{
qSort(vec, k, beg, loc - 1);
qSort(vec, k, loc + 1, end);
}
}
vector<int> GetLeastNumbers_Solution(vector<int> vec, int k) {
if (vec.empty() || k > vec.size())
{
vector<int> ret;
return ret;
}
qSort(vec, k, 0, vec.size() - 1);
vector<int> r(vec.begin(), vec.begin() + k);
return r;
}
};
//基于堆排序
class Solution {
public:
//当一个节点进行了调整后,子树可能不满足堆了,所以要递归调整子节点
void adjust(vector<int> &vec, int i, int len)
{
int lChildIndex = i * 2 + 1;
if (lChildIndex >= len)
{
return;
}
int rChildIndex = i * 2 + 2;
if (rChildIndex >= len)
{
if (vec[lChildIndex] < vec[i])
{
swap(vec[lChildIndex], vec[i]);
}
}
else
{
if (vec[lChildIndex] <= vec[rChildIndex] && vec[lChildIndex] < vec[i])
{
swap(vec[lChildIndex], vec[i]);
adjust(vec, lChildIndex, len);
}
if (vec[rChildIndex] < vec[lChildIndex] && vec[rChildIndex] < vec[i])
{
swap(vec[rChildIndex], vec[i]);
adjust(vec, rChildIndex, len);
}
}
}
void buildMinTopHeap(vector<int> &vec)
{
for (int i = vec.size() / 2 - 1; i >= 0; --i)
{
adjust(vec, i, vec.size());
}
}
void heapSort(vector<int> &vec, int k)
{
buildMinTopHeap(vec);
int len = vec.size();
for (int i = 0; i < k; ++i)
{
swap(vec[0], vec[len - 1]);
adjust(vec, 0, --len);
}
}
vector<int> GetLeastNumbers_Solution(vector<int> vec, int k) {
if (vec.empty() || k > vec.size())
{
vector<int> ret;
return ret;
}
heapSort(vec, k);
vector<int> r(vec.rbegin(), vec.rbegin() + k);
return r;
}
};