携手创作,共同成长!这是我参与「掘金日新计划 · 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) <= 1000000 <= k <= min(100000, len(arr))
思路分析
方法一
- 分析题目可以得知需要的结果是按照升序排列返回前
k项; - 因此很容易就会想到使用数组的
sort方法,排序后再使用slice获取数组的 前k项; - 但是算法题目肯定不是让我们使用这种方法的,因此还有方法二。
方法二
- 跟方法一的思路一样,只是排序方式不同,该方法中采用快速排序的方式进行排序后再取值;
- 快速排序采用分治法将一个串行分割成两个,步骤为先从数组中挑出一个基准值,然后把小于基准值的数值放到左侧,将大于基准值的数值放到右侧,这样一次排列下来就将数组分成了两部分,然后递归的分别处理左侧和右侧的数据,最后可以得到一个升序的数组,这样就达到了排序的效果;
- 最后取 前k项 返回即可。
| arr | left | right | index |
|---|---|---|---|
| [ 1, 3, 5, 9, 10, 7, 2, 4, 6, 8 ] | 0 | 9 | 0 |
| [ 1, 2, 3, 9, 10, 7, 5, 4, 6, 8 ] | 1 | 9 | 2 |
| [ 1, 2, 3, 8, 7, 5, 4, 6, 9, 10 ] | 3 | 9 | 8 |
| [ 1, 2, 3, 6, 7, 5, 4, 8, 9, 10 ] | 3 | 7 | 7 |
| [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] | 3 | 6 | 5 |
| [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] | 3 | 4 | 3 |
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