zoukankan      html  css  js  c++  java
  • 【面试题30】最小的k个数

    【题目描述】

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

    【解决方案】

    测试用例:

    1. 功能测试(输入数组中有相同的数字,输入数组中没有相同的数字);

    2. 边界值测试(输入的k等于1或者等于数组的长度);

    3. 特殊情况测试(k小于1,k大于数组的长度,指向数组的指针为null);

    解法一:基于Partition函数来解决

    优点:时间复杂度为o(n);

    缺点:会修改原数组;不适用于数据量较大的查找(例如,数组一次性加载不到内存中);

    我的代码实现,仅供参考:

     1         public static void GetLeastNums(int[] arr, int k)
     2         {
     3             if (arr == null || arr.Length < k || k <= 0)
     4                 return;
     5 
     6             int start = 0;
     7             int end = arr.Length - 1;
     8             int index = Partition(arr, start, end);
     9 
    10             while (k - 1 != index)
    11             {
    12                 if (index > k - 1)
    13                 {
    14                     end = index - 1;
    15                     index = Partition(arr, start, end);
    16                 }
    17                 else
    18                 {
    19                     start = index + 1;
    20                     index = Partition(arr, start, end);
    21                 }
    22             }
    23 
    24             for (int i = 0; i < k; i++)
    25             {
    26                 Console.Write(arr[i]);
    27             }
    28         }
    29 
    30         public static int Partition(int[] arr, int start, int end)
    31         {
    32             int temp = arr[start];
    33 
    34             while (start < end)
    35             {
    36                 while (start < end && arr[end] >= temp)
    37                     end--;
    38                 arr[start] = arr[end];
    39 
    40                 while (start < end && arr[start] <= temp)
    41                     start++;
    42                 arr[end] = arr[start];
    43             }
    44 
    45             arr[start] = temp;
    46 
    47             return start;
    48         }

    解法二:利用大根堆的特性,在堆中保存前k个小的数,遍历数组,满足则替换

    优点:不需要修改原数组;适合数据量大,所求k较小的情况;

    缺点:时间复杂度为O(nlogk);

    我的代码实现,仅供参考:

     1         public static void GetLeastNums(int[] arr, int k)
     2         {
     3             if (arr == null || arr.Length < k || k <= 0)
     4                 return;
     5 
     6             int[] arrK = new int[k];
     7 
     8             //为大根堆数组赋值
     9             for (int i = 0; i < k; i++)
    10             {
    11                 arrK[i] = arr[i];
    12             }
    13 
    14             //构建大根堆
    15             for (int j = arrK.Length / 2 - 1; j >= 0; j--)
    16             {
    17                 MaxHeapify(arrK, j);
    18             }
    19 
    20             for (int i = k; i < arr.Length; i++)
    21             {
    22                 //如果比大根堆的最大值还要大,则覆盖最大值,然后调整大根堆
    23                 if (arrK[0] > arr[i])
    24                 {
    25                     arrK[0] = arr[i];
    26                     MaxHeapify(arrK, 0);
    27                 }
    28             }
    29 
    30             foreach (int num in arrK)
    31                 Console.Write(num);
    32         }
    33 
    34         /// <summary>
    35         /// 调整大根堆
    36         /// </summary>
    37         /// <param name="arr"></param>
    38         public static void MaxHeapify(int[] arr, int currentIndex)
    39         {
    40             int left = currentIndex * 2 + 1;
    41             int right = currentIndex * 2 + 2;
    42             int large = currentIndex;
    43 
    44             if (left < arr.Length && arr[left] > arr[large])
    45             {
    46                 large = left;
    47             }
    48 
    49             if (right < arr.Length && arr[right] > arr[large])
    50             {
    51                 large = right;
    52             }
    53 
    54             if (large != currentIndex)
    55             {
    56                 Swap(arr, large, currentIndex);
    57 
    58                 MaxHeapify(arr, large);
    59             }
    60         }
    61 
    62         public static void Swap(int[] arr, int indexA, int indexB)
    63         {
    64             int temp = arr[indexA];
    65             arr[indexA] = arr[indexB];
    66             arr[indexB] = temp;
    67         }
  • 相关阅读:
    composer npm bower 版本依赖符号说明
    FastAdmin 速极后台框架从 v1.0 到 v1.2 的数据库升级
    FastAdmin 也可以出书了
    FastAdmin 开发时用到的 Git 命令 (2020-09-26)
    FastAdmin用什么弹窗组件
    笔记:Linux 文件权限
    笔记:使用源代码在 Centos 7 安装 Git 2
    php gd 生成表格 图片
    easyui datagrid 清空
    mysql 去重
  • 原文地址:https://www.cnblogs.com/HuoAA/p/4813480.html
Copyright © 2011-2022 走看看