目录
基础补充
vector的使用方法:https://yq.aliyun.com/articles/272337
文中提到需要特别注意:
使用vector需要注意以下几点
1、如果你要表示的向量长度较长,需要为向量内部保存很多数容易导致内存泄漏而且效率会很低
2、Vector作为函数的参数或者返回值时需要注意它的写法
double Distance(vector<int>&a, vector<int>&b) 其中的“&”绝对不能少
解法一:输入数组排序,然后取前k个
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int n = input.size();
vector<int> result;
if(n<k || input.empty() || k<=0) return result;
sort(input.begin(), input.end());
for(int i=0; i<k; i++){
result.push_back(input[i]);
}
return result;
}
};
解法二:基于Partition函数
一开始一直报段错误,一直查找不出问题。后来试了试把函数最后的赋值语句改成push_back,就可以通过了。
原来的写法引发段错误的原因:
vector的几种初始化及赋值方式:https://blog.youkuaiyun.com/yjunyu/article/details/77728410
上文中提到了,vector初始化时不带参数的话,默认size为0,这种情况下不用push_back而是直接用索引,肯定会索引越界,报段错误的。
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int n = input.size();
vector<int> result;
if(input.empty() || n<k || k<=0) return result;
int begin = 0;
int end = n-1;
int index = Partition(input, begin, end);
while(index!=k-1){
if(index<k-1){
begin = index+1;
index = Partition(input, begin, end);
}
else{
end = index-1;
index = Partition(input, begin, end);
}
}
//index指向第k位,左边均为小于它的数字,0~(k-1)位,共k个数字
//1:循环赋值
for(int i=0; i<k; i++){
//result[i] = input[i]; //会发生段错误,为什么???
result.push_back(input[i]);
}
//2:切片式的方法
vector<int> result1(input.begin(),input.begin()+k);
return result;
}
int Partition(vector<int> &data, int begin, int end)
{
int k = begin + (rand()%(end-begin+1)); //随机选取一个区间内的数
swap(data[k], data[end]);
int small = begin-1;
for(int i=begin; i<end; i++){
if(data[i]<data[end]){
small++;
if(small!=i) swap(data[small], data[i]);
}
}
small++;
swap(data[small], data[end]);
return small;
}
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
};
解法三:最大堆/最小堆
3.1 时间复杂度O(nlogn)空间复杂度O(n)
最大堆,很简单明了的做法:
但是时间复杂度高,是O(nlogn),空间复杂度高,是O(n),因为我是把整个vector中的数据全部放入最大堆,不断弹出,剩下k个,就是k个最小的。
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
//最大堆
int n = input.size();
vector<int> res; //初始化一个size为0的vector (怪不得之前不用push_back方法老是报段错误)
if(input.empty() || n<k || k<=0)
return res;
priority_queue<int> pq(input.begin(), input.end());
for (int i=0; i<n-k; i++){
pq.pop();
}
vector<int> Res(k); //初始化size,但每个元素值为默认值0
for(int i=k-1; i>=0; i--){
Res[i] = pq.top(); //这种写法又引发了段错误!看来是vector容器没有赋值之前不可以随意用索引
pq.pop();
}
return Res;
}
};
最小堆:好处和上面一样,同样是简洁明了。坏处也类似,同样用堆,时间复杂度空间复杂度都可以再提高。
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
//最小堆
int n = input.size();
vector<int> res;
if(input.empty() || n<k || k<=0)
return res;
priority_queue<int, vector<int>, greater<int> > pq(input.begin(), input.end());
for (int i=0; i<k; i++){
res.push_back(pq.top()); //每次压入当前最小值
pq.pop();
}
return res;
}
};
3.2 时间复杂度O(nlogk)空间复杂度O(k)
最大堆:
最小堆:
解法四:红黑树:multiset集合
(待补充)
Python排序实现
参考我的另一篇博客:https://blog.youkuaiyun.com/chengda321/article/details/93487276
博客介绍了求数组中前k个最小元素的多种解法,包括对输入数组排序取前k个、基于Partition函数、使用最大堆/最小堆、红黑树(multiset集合),还提及Python排序实现。同时补充了vector使用注意事项及初始化赋值方式,分析了部分解法的时间和空间复杂度。
335

被折叠的 条评论
为什么被折叠?



