0
点赞
收藏
分享

微信扫一扫

[数组]BM46 最小的K个数-中等

​​BM46 最小的K个数​​

描述

给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。数据范围:[数组]BM46 最小的K个数-中等_最小的k个数,数组中每个数的大小[数组]BM46 最小的K个数-中等_快排_02要求:空间复杂度 [数组]BM46 最小的K个数-中等_快排_03 ,时间复杂度 [数组]BM46 最小的K个数-中等_快排_04

示例1

输入:

[4,5,1,6,2,7,3,8],4

复制返回值:

[1,2,3,4]

复制说明:

返回最小的4个数即可,返回[1,3,2,4]也可以

示例2

输入:

[1],0

复制返回值:

[]

复制

示例3

输入:

[0,1,2,1,2],3

复制返回值:

[0,1,1]

题解

思路:

这里使用快排的思想可以快速找出前k个最小的数。我们知道一次快排的完毕的时候如果此时中间索引为i,那么i左边的元素都小于该索引处的值,其右边的元素都大于该索引处的值。因此,我们可以知道[0,i-1]是前i个最小的元素,如果i == k ,那么[0,i-1]就是我们要找的前k个元素了,实现代码如下:


#include <bits/stdc++.h>

// 一次快排,返回结束时的索引
int sort_once(std::vector<int> &v, int left, int right)
{
if (left == right)
{
return left;
}

int key = v[left];
while (left < right)
{
while (v[right] >= key && right > left)
{
right--;
}
std::swap(v[left], v[right]);
while (v[left] <= key && left < right)
{
left++;
}
std::swap(v[left], v[right]);
}
v[left] = key;
return left;
}

std::vector<int> GetLeastNumbers_Solution(std::vector<int> input, int k)
{
int left = 0;
int right = input.size() - 1;
while (left <= right)
{
int pos = sort_once(input, left, right);
if (pos == k - 1)
{
right = pos;
break;
}
else if (pos > k - 1)
{
right = pos - 1;
}
else
{
left = pos + 1;
}
}
std::vector<int> v{input.begin(), input.begin() + k};
return v;
}
举报

相关推荐

0 条评论