zoukankan      html  css  js  c++  java
  • 剑指 Offer 40. 最小的k个数(简单)

    通过率 56.9%

    题目链接

    题目描述:

    输入整数数组 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]

    示例 2:

    输入:arr = [0,1,2,1], k = 1
    输出:[0]

    限制:

    0 <= k <= arr.length <= 10000
    0 <= arr[i] <= 10000

    思路:

    1. 库函数 sort + slice

    2. 堆 C++可以直接用priority_queue优先队列,遍历数组,用优先队列维护最小的k个值,一旦当前遍历到的数小于大顶堆堆顶的数,就将堆顶的数弹出让当前的数入队,最后返回该优先队列中的数

    3. 快速排序 每排一次都会将数组分为两组排序,设分割点的值为x,那么左边那组数都比x小,右边的都比x大,于是,当x===k-1时,直接返回数组前k个数(由题可知,返回的数组可以无序,只要保证是前k小的数就行);当x<k-1,则只须排右边那组;当x>k-1,只须排左边那组

    代码:

    1. 库函数 sort + slice

     1 /*JavaScript*/
     2 /**
     3  * @param {number[]} arr
     4  * @param {number} k
     5  * @return {number[]}
     6  */
     7 var getLeastNumbers = function(arr, k) {
     8     arr.sort((a, b) => a - b)
     9     return arr.slice(0, k)
    10 };

    2. 堆(优先队列)

     1 /*C++*/
     2 class Solution {
     3 public:
     4     vector<int> getLeastNumbers(vector<int>& arr, int k) {
     5         vector<int> res;
     6         priority_queue<int> q;
     7 
     8         if(!k) return res;
     9         for(int i = 0; i < k; i++) {
    10             q.push(arr[i]);
    11         }
    12         for(int i = k; i < arr.size(); i++) {
    13             if(arr[i] < q.top()) {
    14                 q.pop();
    15                 q.push(arr[i]);
    16             }
    17         }
    18         while(q.size()) {
    19             res.push_back(q.top());
    20             q.pop();
    21         }
    22         return res;
    23     }
    24 };

    3. 快排

    这里将第一个数作为基准点会好分析一些,最后跳出循环时一定是i===j,而以其他数作为基准点的话我往往很难确定到底是i还是j是分割点,分治就是这点令人头疼,不知道分到最后是个什么情况,说到底还是对这个不熟

     1 /*JavaScript*/
     2 /**
     3  * @param {number[]} arr
     4  * @param {number} k
     5  * @return {number[]}
     6  */
     7 var quickSort = function(arr, left, right) {
     8     let i = left, j = right, v = arr[left]
     9     while(i < j) {
    10         while(i < j && arr[j] >= v) j--
    11         arr[i] = arr[j]
    12         while(i < j && arr[i] <= v) i++
    13         arr[j] = arr[i]
    14     }
    15     arr[i] = v
    16     return i
    17 }
    18 
    19 var partition = function(arr, left, right, k) {
    20     const x = quickSort(arr, left, right, k)
    21     if(x === k) return arr.slice(0, k)
    22     return x < k ? partition(arr, x + 1, right, k) : partition(arr, left, x - 1, k)
    23 }
    24 
    25 var getLeastNumbers = function(arr, k) {
    26     return partition(arr, 0, arr.length - 1, k)
    27 };
  • 相关阅读:
    .net core 3.1 使用Redis缓存
    JavaSE 高级 第11节 缓冲输入输出字节流
    JavaSE 高级 第10节 字节数组输出流ByteArrayOutputStream
    JavaSE 高级 第09节 字节数组输入流ByteArrayInputStream
    JavaSE 高级 第08节 文件输出流FileOutputStream
    JavaSE 高级 第07节 文件输入流FileInputStream
    JavaSE 高级 第06节 初识I、O流
    JavaSE 高级 第05节 日期类与格式化
    JavaSE 高级 第04节 StringBuffer类
    JavaSE 高级 第03节 Math类与猜数字游戏
  • 原文地址:https://www.cnblogs.com/wwqzbl/p/15209779.html
Copyright © 2011-2022 走看看