【leetcode】堆习题

215.数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4], k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var findKthLargest = function(nums, k) {
    let arr = new MinHeap()
    nums.forEach(item => {
        arr.insert(item)
        if (arr.size() > k) {
            arr.pop()
        }
    })
    return arr.peek()
};

class MinHeap {
    constructor() {
        this.heap = []
    }
    // 换位置
    swap(i1, i2) {
        let temp = this.heap[i1]
        this.heap[i1] = this.heap[i2]
        this.heap[i2] = temp
    }
    // 找到父节点
    getParentIndex(index) {
        return Math.floor((index - 1) / 2)
    }
    // 上(前)移操作
    up(index) {
        if (index === 0) return
        const parentIndex = this.getParentIndex(index)
        if (this.heap[parentIndex] > this.heap[index] ) {
            this.swap( parentIndex, index )
            this.up(parentIndex)
        }
    }
    // 找到左侧子节点
    getLeftIndex(index) {
        return index * 2 + 1
    }
    // 找到右侧子节点
    getRigthIndex(index) {
        return index * 2 + 2
    }
    // 下(后)移操作
    down(index) {
        const leftIndex = this.getLeftIndex(index)
        const rightIndex = this.getRigthIndex(index)
        if (this.heap[leftIndex] < this.heap[index]) {
            this.swap(leftIndex, index)
            this.down(leftIndex)
        }
        if (this.heap[rightIndex] < this.heap[index]) {
            this.swap(rightIndex, index)
            this.down(rightIndex)
        }
    }
    // 添加元素
    insert( value ) {
        this.heap.push(value)
        this.up( this.heap.length-1 )
    }
    // 删除堆顶
    pop() {
        this.heap[0] = this.heap.pop()
        this.down(0)
    }
    // 获取堆顶
    peek() {
        return this.heap[0]
    }
    // 获取堆长度
    size() {
        return this.heap.length
    }
}

LCR 159. 库存管理 III(计数排序
仓库管理员以数组 stock 形式记录商品库存表,其中 stock[i] 表示对应商品库存余量。请返回库存余量最少的 cnt 个商品余量,返回 顺序不限。
示例 1:
输入:stock = [2,5,7,4], cnt = 1
输出:[2]
示例 2:
输入:stock = [0,2,3,6], cnt = 2
输出:[0,2] 或 [2,0]
提示:
0 <= cnt <= stock.length <= 10000
0 <= stock[i] <= 10000

/**
 * @param {number[]} stock
 * @param {number} cnt
 * @return {number[]}
 */

// 原生API
var inventoryManagement = function(stock, cnt) {
    return stock.sort((a,b) => a-b).slice(0, cnt)
};

// 计数排序 用空间换时间
var inventoryManagement = function(stock, cnt) {
    return countingSort(stock, cnt, 10000)
};
let countingSort = (arr, k, maxValue) => {
    let bucket = new Array(maxValue),
    sortedIndex = 0,
    arrLen = arr.length
    bucketLength = maxValue
    // 生成 bucket. 示例:stock = [2,5,7,4],则 bucket = [0, 0, 1, 0, 1, 1, 0, 1]
    for (let i = 0; i < arrLen; i++) {
        if (!bucket[arr[i]]) {
            bucket[arr[i]] = 0
        }
        bucket[arr[i]]++
    }
    let res = []
    for (let j = 0; j < bucketLength; j++) {
        while (bucket[j]-- > 0 && sortedIndex < k) {
            res[sortedIndex++] = j
        }
        if (sortedIndex === k) {
            break
        }
    }
    return res
}

347.前 K 个高频元素
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
1 <= nums.length <= 105
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var topKFrequent = function(nums, k) { // nums = [1,1,1,2,2,3]
    let map = new Map()
    let arr = [...new Set(nums)] // [1,2,3]
    nums.map(num => {
        if (map.has(num)) {
            map.set(num, map.get(num) + 1)
        } else {
            map.set(num, 1)
        }
    })
    return arr.sort((a, b) => map.get(b) - map.get(a)).slice(0, k)
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值