输入: [3,2,1,5,6,4], k = 2
输出: 5
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
1 )基于js中原生sort api
const findKthLargest = function(nums, k) {
return nums.sort((a,b) => b-a)[k - 1]
};
2 )基于堆的数据结构和堆排序的方法
// 建立最小堆类
class MinHeap {
heap: number[] = [];
// 交换节点位置
swap(i, j) {
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
}
// 获得父节点
getParentIndex(i) {
return (i - 1) >> 1;
}
// 获取左子节点
getLeftIndex(i) {
return (i << 1) + 1; // 极客写法
}
// 获取右子节点
getRightIndex(i) {
return (i << 1) + 2;
}
// 向上移动
shiftUp(index) {
// 如果到了堆顶元素,index是0,则不要再上移了
if(!index) return;
const parentIndex = this.getParentIndex(index)
if(this.heap[parentIndex] > this.heap[index]) {
this.swap(parentIndex, index)
this.shiftUp(parentIndex)
}
}
// 下移
shiftDown(index) {
// 边界1:如果到了堆尾元素,则不要再下移了
if(index >= this.heap.length - 1) return;
const size = this.size();
const leftIndex = this.getLeftIndex(index);
const rightIndex = this.getRightIndex(index);
if (leftIndex < size && this.heap[leftIndex] < this.heap[index]) {
this.swap(leftIndex, index);
this.shiftDown(leftIndex);
}
if (rightIndex < size && this.heap[rightIndex] < this.heap[index]) {
this.swap(rightIndex, index);
this.shiftDown(rightIndex);
}
}
// 插入
insert(value) {
this.heap.push(value);
this.shiftUp(this.heap.length - 1);
}
// 删除堆顶
pop() {
// pop()方法删除数组最后一个元素并返回,赋值给堆顶
this.heap[0] = this.heap.pop();
// 对堆顶重新排序
this.shiftDown(0);
}
// 获取堆顶
peak() {
return this.heap[0];
}
// 获取堆的大小
size() {
return this.heap.length;
}
}
// 实现
const findKthLargest = (nums, k) => {
const h = new MinHeap();
nums.forEach(n => {
// 将数组元素依次插入堆中
h.insert(n);
// 如果堆满,则执行优胜劣汰
(h.size() > k) && h.pop();
})
// 返回堆顶,此时就是第k大的元素
return h.peak();
};
3 )基于冒泡排序
function findKthLargest(nums: number[], k: number): number {
const len = nums.length - 1;
for (let i = len; i > len - k; i--) {
for (let j = 0; j < i; j++) {
if (nums[j] > nums[j + 1]) {
[nums[j], nums[j + 1]] = [nums[j + 1], nums[j]];
}
}
}
return nums[len - k + 1];
};
4 )基于快速排序
function quickselect(nums: number[], l: number, r: number, k: number) {
if (l == r) return nums[k];
const pivot = nums[l];
let i:number = l - 1, j:number = r + 1;
while (i < j) {
do i++; while (nums[i] < pivot);
do j--; while (nums[j] > pivot);
if (i < j) [nums[i], nums[j]] = [nums[j], nums[i]];
}
return k <= j ? quickselect(nums, l, j, k) : quickselect(nums, j + 1, r, k);
}
function findKthLargest(nums: number[], k: number): number {
const n = nums.length;
return quickselect(nums, 0, n - 1, n - k);
}