寻找最大的k个数



问题:

找出一个序列中最大的k个数。

解法:

一、假设N个数存储在数组S中,我们从数组S随机找出一个元素X,把数组分成为两个部分Sa和Sb。Sa中元素大于等于X,Sb中的元素小于X。

则有两种可能性:1.Sa中元素的个数小于k,Sa中所有的数的和Sb中最大的k-|Sa|个元素就是S中最大的k个数。
                2.Sa中的个数大于或等于k,则返回Sa中最大的k个元素。

    平均时间复杂度O(N*logk)。

 二、建堆,通过建立k的小根堆来解决。平均时间复杂度O(N*logk)。


代码:

#include <iostream>
#include <vector>

using namespace std;

{//方法二:可用priority_queue实现,priority_queue实际上是由大根堆实现。
    
    void minheap(int * S, int k)
    {

    }
}

{//方法一:


void Partition(vector<int> S, vector<int> &Sa, vector<int> &Sb )
{
    int p = S.front();
    for(int i=1;i<S.size();i++)
    {
        if(S[i] > p)
            Sa.push_back(S[i]);
        else
            Sb.push_back(S[i]);
    }
    Sa.size() < Sb.size()? Sa.push_back(p):Sb.push_back(p);
}

vector<int> Append(vector<int> a,vector<int> b)
{
    while(!b.empty())
    {
        a.push_back(b.back());
        b.pop_back();
    }
    return a;
}
}

vector<int> Kbig(vector<int> S, int k)
{
    if(k <= 0)//k小于0时返回空
    {
        vector<int> temp;
        return temp ;
    }
    if(S.size() <= k)//S的长度小于等于k则返回S即可。
        return S;
    else
    {
        vector<int> Sa, Sb;
        Partition(S, Sa, Sb);//将S分段
        //统一处理:(1)Sa的个数小于k则需加上Sb中元素,不小于k则后一个返回空,不影响结果。
        return Append(Kbig(Sa,k),Kbig(Sb,k-Sa.size()));
    }
}

int main()
{
    vector<int> S = {1,2,3,4,5,6,7,8,9};
    vector<int> res = Kbig(S,3);
    while(!res.empty())
    {
        cout << res.back() << " ";
        res.pop_back();
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言实现桶排序找最小的k个数的示例代码: ``` #include <stdio.h> #include <stdlib.h> #include <limits.h> void bucket_sort(int arr[], int n, int k) { int max_num = INT_MIN, min_num = INT_MAX; for (int i = 0; i < n; i++) { if (arr[i] > max_num) { max_num = arr[i]; } if (arr[i] < min_num) { min_num = arr[i]; } } int bucket_size = (max_num - min_num) / k + 1; int **buckets = (int **)malloc(bucket_size * sizeof(int *)); for (int i = 0; i < bucket_size; i++) { buckets[i] = (int *)malloc(n * sizeof(int)); } int *counters = (int *)malloc(bucket_size * sizeof(int)); for (int i = 0; i < bucket_size; i++) { counters[i] = 0; } for (int i = 0; i < n; i++) { int index = (arr[i] - min_num) / k; buckets[index][counters[index]] = arr[i]; counters[index]++; } int count = 0; for (int i = 0; i < bucket_size; i++) { for (int j = 0; j < counters[i]; j++) { arr[count] = buckets[i][j]; count++; if (count == k) { break; } } if (count == k) { break; } } for (int i = 0; i < bucket_size; i++) { free(buckets[i]); } free(buckets); free(counters); } int main() { int arr[] = { 5, 2, 8, 3, 9, 1, 6, 4, 7 }; int n = sizeof(arr) / sizeof(arr[0]); int k = 4; bucket_sort(arr, n, k); printf("The smallest %d numbers are: ", k); for (int i = 0; i < k; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; } ``` 在这个示例代码中,我们先找到输入数组中的最大值和最小值,然后根据最大值和最小值计算出桶的大小。然后我们创建一个二维数组buckets来保存桶,一个一维数组counters来保存每个桶中元素的数量。接下来,我们将输入数组中的元素分配到各个桶中,然后按照桶的顺序将桶中的元素合并到输入数组中。最后,我们释放桶和计数器的内存。 在main()函数中,我们定义了一个输入数组arr和一个整数k。我们将arr和数组的大小n传递给bucket_sort()函数,然后输出最小的k个数字。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值