347. 前 K 个高频元素 JavaScript实现

347. 前 K 个高频元素

题目链接

先用哈希表Map统计每个数据的个数,然后进行排序操作。重要的是排序操作,如果要求是优于 O ( n log ⁡ n ) O(n \log n) O(nlogn),则可供选择的只有堆排序和同排序。

一、哈希表 + 内置sort

sort时间复杂度为为O(nlogn)

var topKFrequent = function(nums, k) {
    // 使用map统计个数
    let map = new Map()
    for(let num of nums){
        // key是数字,value是个数
        // 如果map中有数字,则在此基础上+1,否则初始为1
        map.set(num,map.get(num) ? map.get(num)+1 : 1)
    }
    //k如果等于map.size,直接返回全部key
    if(map.size == k) return [...map.keys()]
    
    // 内置sort排序:先转化成二维数组,然后使用sort按照二维数组的列进行从大到小的排序
    let arr = Array.from(map).sort((a,b) => b[1] - a[1])
    // 取排序后的数组的前k个.
    // arr.slice(0,k)  [ [ -1, 2 ], [ 2, 2 ] ]。由于只需要每个数组里的第一个元素,所以需要再次处理
    return arr.slice(0,k).map(n=>n[0])    // [ -1, 2 ]
};

二、哈希表+桶排序

  • 桶分类:遍历map,拿到key(数字),value(出现的频率)。把相同频率的数字当在一起,频率作为下标。数组下标i放置频率为i的key
  • 最后倒序取出k个key。因为可以按任意顺序返回答案,所以k如果等于map.size,那么直接返回全部key,不用排序
var topKFrequent = function(nums, k) {
    // 使用map统计个数
    let map = new Map()
    for(let num of nums){
        // key是数字,value是个数
        // 如果map中有数字,则在此基础上+1,否则初始为1
        map.set(num, map.get(num) ? map.get(num)+1 : 1)
    }
    //k如果等于map.size,直接返回全部key
    if(map.size == k) return [...map.keys()]
    
    // 桶排序
    const bucketSort = () => {
        // 结果数组
        let res = []
        // 桶数组,用来将相同频率的放在一个里面
        let arr = []
        map.forEach( (value,key) => {
            // value是分类的频率,把相同的频率放在一个里面
            if(!arr[value]){
                // 把数字放入对应的频率
                arr[value] = [key]
            }else{
                // 相同的频率的数字放在一起
                arr[value].push(key)
            }
        });
        // 排序完成后,从后往前遍历取数据,注意最后结果数组里的长度不超过k
        for(let i=arr.length-1; i>=0 && res.length<k; i--){
            // 注意有些频率是没有数据的
            if(arr[i]){
                res.push(...arr[i])
            }
        }
        return res
    }
    return bucketSort()
};

你可能感兴趣的:(leetcode刷题,#,哈希表,javascript,算法,数据结构)