LeetCode 算法:最小K个数

111 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 29 天,点击查看活动详情

最小K个数

原题地址

设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

示例1:

输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]

示例2:

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

提示:

  • 0 <= len(arr) <= 100000
  • 0 <= k <= min(100000, len(arr))

思路分析

方法一

  1. 分析题目可以得知需要的结果是按照升序排列返回前 k 项;
  2. 因此很容易就会想到使用数组的 sort 方法,排序后再使用 slice 获取数组的 前k项
  3. 但是算法题目肯定不是让我们使用这种方法的,因此还有方法二。

方法二

  1. 跟方法一的思路一样,只是排序方式不同,该方法中采用快速排序的方式进行排序后再取值;
  2. 快速排序采用分治法将一个串行分割成两个,步骤为先从数组中挑出一个基准值,然后把小于基准值的数值放到左侧,将大于基准值的数值放到右侧,这样一次排列下来就将数组分成了两部分,然后递归的分别处理左侧和右侧的数据,最后可以得到一个升序的数组,这样就达到了排序的效果;
  3. 最后取 前k项 返回即可。
arrleftrightindex
[ 1, 3, 5, 9, 10, 7, 2, 4, 6, 8 ]090
[ 1, 2, 3, 9, 10, 7, 5, 4, 6, 8 ]192
[ 1, 2, 3, 8, 7, 5, 4, 6, 9, 10 ]398
[ 1, 2, 3, 6, 7, 5, 4, 8, 9, 10 ]377
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]365
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]343

AC 代码

方法一

/**
 * @param {number[]} arr
 * @param {number} k
 * @return {number[]}
 */
var smallestK = function(arr, k) {
    return arr.sort((a, b) => a - b).slice(0, k)
};

结果:

  • 执行结果: 通过
  • 执行用时:96 ms, 在所有 JavaScript 提交中击败了58.99%的用户
  • 内存消耗:47.2 MB, 在所有 JavaScript 提交中击败了78.65%的用户
  • 通过测试用例:29 / 29

方法二

/**
 * @param {number[]} arr
 * @param {number} k
 * @return {number[]}
 */
var smallestK = function(arr, k) {
    return quickSort(arr).slice(0, k)
};

function quickSort(arr, left, right) {
    const len = arr.length
    let index = -1
    left = typeof left !== 'number' ? 0 : left
    right = typeof right !== 'number' ? len - 1 : right

    if (left < right) {
        index = partition(arr, left, right)
        quickSort(arr, left, index - 1)
        quickSort(arr, index + 1, right)
    }
    return arr
}

function partition(arr, left, right) {     // 分区操作
    const base = left                      // 设定基准值(pivot)
    let index = base + 1
    for (let i = index; i <= right; i++) {
        if (arr[i] < arr[base]) {
            [arr[i], arr[index]] = [arr[index], arr[i]]
            index++
        }        
    }
    [arr[base], arr[index - 1]] = [arr[index - 1], arr[base]]
    return index - 1
}

结果:

  • 执行结果: 通过
  • 执行用时:84 ms, 在所有 JavaScript 提交中击败了88.20%的用户
  • 内存消耗:47 MB, 在所有 JavaScript 提交中击败了91.01%的用户
  • 通过测试用例:29 / 29

END