掘金团队号上线,助你 Offer 临门! 点击 查看详情
题目描述
输入整数数组 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]
解题思路
这道题有两种解法:
解法一:
- 对数组进行排序,数组排序的方法有很多,本文采用了快速排序;
- 利用js的splice或者slice,切数组的前k个返回
解法二:如果学过数据结构堆,就可以利用堆来进行排序,需要维护一个小根堆(一般指最小堆。最小堆,是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于其左子节点和右子节点的值),排序后堆中的前k个元素就是要返回的结果。
解题代码
解法一代码:
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
let centerIndex = Math.floor(arr.length / 2);
let centerValue = arr.splice(centerIndex, 1)[0];
let left = [], right = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < centerValue) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return quickSort(left).concat([centerValue], quickSort(right))
}
var getLeastNumbers = function (arr, k) {
const minList = quickSort(arr);
return minList.slice(0, k);
};
解法二代码:
function buildHeap(arr) {
let len = arr.length;
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapAdjust(arr, i, len);
}
}
// 变量交换
function swap(arr, i, child) {
if (i === child) return;
arr[i] = arr[child] + arr[i];
arr[child] = arr[i] - arr[child];
arr[i] = arr[i] - arr[child];
}
var getLeastNumbers = function (arr, k) {
let len = arr.length;
let res = [];
if (k === 0) return [];
if (k === len) return arr;
buildHeap(arr);
for (let i = 1; i <= k; i++) {
res.push(arr[0]);
swap(arr, 0, len - i);
heapAdjust(arr, 0, len - i);
}
return res;
};
function heapAdjust(arr, i, len) {
let child = i * 2 + 1;
while (child < len) {
if (child + 1 < len && arr[child] > arr[child + 1]) {
child = child + 1;
}
if (arr[child] < arr[i]) {
swap(arr, i, child);
i = child;
child = i * 2 + 1;
} else {
break;
}
}
}
总结
解法二虽然代码较多,但是它体现是是一种思维方式,利用数据结构去解决这个问题。