• 最小的k个数


      题目来源:《剑指offer》面试题30

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

      解法一:利用快速排序Partition的思想来解决这个问题。如果基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数组的左边,比第k个数字大的所有数字都位于数组的右边。这样调整之后,位于数组中左边的k个数字就是最小的k个数字(这k个数字不一定是排序的)。

      采用这种思想是有限制的。我们需要修改输入的数组,因为函数Partition会调整数组中数字的顺序。

      时间复杂度O(n)

    void GetLeastNumbers(int* input, int n, int *output, int k) {
        if (input == NULL || output == NULL || k > n || n <= 0 || k >= 0)
            return;
    
        int start = 0;
        int end = n - 1;
        int index = Partition(input, start, end);
    
        while (index != k - 1) {
            if (index > k - 1) {
                end = index - 1;
                index = Partition(input, n, output, k);
            } else {
                start = index + 1;
                index = Partition(input, n, output, k);
            }
        }
    
        for (int i = 0; i < k; i++)
            output[i] = input[i];
    }

      解法二:可以利用k堆排序来解决这个问题。这种方法没有修改数组并且适合海量数据处理。

          时间复杂度O(nlgn)

    void BuildMaxHeap(int* numbers, int len) {
        for (int i = len / 2; i >= 0; i--) {
            AdjustDown(numbers, i, len - 1);
        }
    }
    
    void AdjustDown(int* numbers, int key, int heap_size) {
        int temp = numbers[key];
        for (int child = key << 1 + 1; child <= heap_size; key = child) {
            if (child < heap_size && numbers[child] < numbers[child + 1])
                child++;
    
            if (temp < numbers[child])
                a[i] = a[child];
            else 
                break;
        }
    
        numbers[key] = temp
    }
    
    void GetLeastNumbers(int* input, int n, int *output, int k) {
        if (input == NULL || output == NULL || k > n || n <= 0 || k <= 0)
            return;
    
        int index = 0;
        for (; index < k; index++)
            output[index] = input[index];
        BuildMaxHeap(output, k);
        for (;index < n; index++) {
            if (numbers[index] < output[0]) {
                output[0] = numbers[index];
                AdjustDown(numbers, 0, k - 1);
            } 
        }
    }
  • 相关阅读:
    .Net Core 为 x86 和 x64 程序集编写 AnyCPU 包装
    动态构造任意复杂的 Linq Where 表达式
    Windows GDI 窗口与 Direct3D 屏幕截图
    你一定看得懂的 DDD+CQRS+EDA+ES 核心思想与极简可运行代码示例
    浏览器中的 .Net Core —— Blazor WebAssembly 初体验
    Asp.Net Core IdentityServer4 管理面板集成
    Asp.Net Core Identity 骚断腿的究极魔改实体类
    lambda函数的作用
    风控模型师面试准备--业务+模型篇
    梯度下降算法原理讲解
  • 原文地址:https://www.cnblogs.com/vincently/p/4780887.html
Copyright © 2020-2023  润新知