持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
一、题目
描述:
给定一个长度为n的可能有重复值的数组,找出其中不去重的最小的k个数。
例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
#include <iostream>
#include <vector>
using namespace std;
vector<int> getLowNumbers(vector<int>& array, int count){
}
int main(int, char*[])
{
vector<int> array = {4, 5, 1, 6, 2, 7, 3 ,8};
vector<int> data = getLowNumbers(array, 4);
for(int i = 0; i < 4; ++i){
cout << data.at(i) << ' ';
}
cout << endl;
}
二、分析
由题意可知,我们要输出的结果为k个最小的数,那剩下的n-k个数就都是没用的,既然如此,我们只需要先拿k个数,然后再不断的用剩下的n-k个数对k个数进行比较,有更小的就替换,保持k个数是最小的就行了。
为了保证更好的效率,我们用链表来承载K个数,并且保持有序,再比较替换的时候就只需要与最外层的数比较。
三、模拟
- 先拿到4个数
[4,5,1,6] - 排序
[1,4,5,6] - 开始用剩下的数去比较并替换 2 -> [1,2,4,5]
- 7 -> 不变
- 3 -> [1,2,3,4]
- 8 -> 不变
四、实现
class QyList{
public:
struct Node{
Node(int val): val(val), next(nullptr) {}
int val;
Node* next;
};
Node desc;
QyList(vector<int>& vector, int n): desc(0){
while(n){
push(vector.at(--n));
}
}
void push(int val){
Node* cur = &desc;
Node* vn = new Node(val);
while(cur->next && cur->next->val > val){
cur = cur->next;
}
vn->next = cur->next;
cur->next = vn;
}
void pop(){
Node* cur = desc.next;
desc.next = cur->next;
delete cur;
}
void tryPush(int val){
if(desc.next->val > val){
pop();
push(val);
}
}
};
vector<int> getLowNumbers(vector<int>& array, int count){
vector<int> result;
if(array.empty() || count == 0) return result;
result.reserve(count);
QyList ll(array, count);
for(int i = count; i < array.size(); ++i){
ll.tryPush(array.at(i));
}
QyList::Node* cur = ll.desc.next;
while (cur) {
result.push_back(cur->val);
cur = cur->next;
}
return result;
}
五、结言
这道题难度比较低,本着对算法的学习与熟练,写的稍微底层麻烦了一些,在实际写的时候,可以使用标准库,利于维护。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!