每日一算法题-寻找最小的数

94 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

一、题目

描述:
给定一个长度为n的可能有重复值的数组,找出其中不去重的最小的k个数。
例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。

image.png

#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个数,并且保持有序,再比较替换的时候就只需要与最外层的数比较。

三、模拟

  1. 先拿到4个数
    [4,5,1,6]
  2. 排序
    [1,4,5,6]
  3. 开始用剩下的数去比较并替换 2 -> [1,2,4,5]
  4. 7 -> 不变
  5. 3 -> [1,2,3,4]
  6. 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;
}

五、结言

这道题难度比较低,本着对算法的学习与熟练,写的稍微底层麻烦了一些,在实际写的时候,可以使用标准库,利于维护。

创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!