《剑指OFFER》中 “最小的k个数”

题目描述:输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

示例 1:

输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]

我首先想到的是最基础的解法,通过冒泡排序对原数组进行排序,然后取最小的那几个数字
以下是代码:

int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
    int i=0,j=0;
    int *ret = (int *)calloc(sizeof(int),k);
    *returnSize = k;
    int mid ;
    for(i=0;i<arrSize;i++)
    {
        for(j=0;j<i;j++)
        {
            if(arr[i]<arr[j])
            {
                mid = arr[i];
                arr[i] = arr[j];
                arr[j] = mid;
            }
        }
    }
    for(i=0;i<k;i++)
    {
        ret[i] = arr[i];
    }
    return ret;
}

但是,这样的话,时间复杂度太高了,如果遇到很多数字,需要计算很久,我贴上在力扣刷题时的时间

在这里插入图片描述第二种算法就是 使用自带的stdlib库的qsort快排函数进行排序
这里贴出qsort函数的使用方法:

函数声明
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void , const void))
参数

base-- 指向要排序的数组的第一个元素的指针。
nitems-- 由 base 指向的数组中元素的个数。
size-- 数组中每个元素的大小,以字节为单位。
compar-- 用来比较两个元素的函数,即函数指针(回调函数)

回调函数: 回调函数就是一个通过函数指针调用的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就说这是回调函数。
[2]
compar参数 compar参数指向一个比较两个元素的函数。比较函数的原型应该像下面这样。注意两个形参必须是const void *型,同时在调用compar 函数(compar实质为函数指针,这里称它所指向的函数也为compar)时,传入的实参也必须转换成const void *型。在compar函数内部会将const void *型转换成实际类型。
int compar(const void *p1,const void *p2);
如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的左面;
如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定;   
如果compar返回值大于0(>0),那么p1所指向元素会被排在p2所指向元素的右面。
在这里插入图片描述所以,代码如下:

int cmp(void *a, void *b)
 {
     return *(int *)a  - *(int *)b;
 }
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
    
    qsort(arr, arrSize, sizeof(int), cmp);  // 从小到大排序

    int *ret = (int *) malloc( sizeof(int) * k );//为返回的值申请空间
    *returnSize = k;    // 

    memcpy(ret, arr, k * (sizeof(int))); // 前K个取出来返回

    return ret;
}

这样一来,用时就缩短了很多在这里插入图片描述
还有二叉树搜索法、堆排序等,就不一一列出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值