074_前K个高频元素

知识点:堆、哈希表

LeetCode第三百四十七题:https://leetcode-cn.com/problems/top-k-frequent-elements/submissions/

语言:GoLang

// 朴素解法,暴力、时间5%, 空间62%
func topKFrequent_(nums []int, k int) []int {
    hMap := map[int]int{}

    for _, v := range nums {
        hMap[v]++
    }

    // fmt.Println(hMap)

    result := []int{}
    for ; k > 0; k-- {
        k, v := 0, 0
        for kk, vv := range hMap {
            if vv >= v {
                k, v = kk, vv
            }
        }
        hMap[k] = 0
        result = append(result, k)
    }

    return result
}




// IntHeap 是一个由整数组成的最小堆。
type IntHeap [][2]int

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i][1] < h[j][1] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *IntHeap) Push(x interface{}) {
	// Push 和 Pop 使用 pointer receiver 作为参数,
	// 因为它们不仅会对切片的内容进行调整,还会修改切片的长度。
	*h = append(*h, x.([2]int))
}

func (h *IntHeap) Pop() interface{} {
    heap := *h
	x := heap[len(heap) - 1]
	*h = heap[ : len(heap) - 1]
	return x
}


// 按照数组统计生成一个hMap,然后将map转化为heap
// 之后按顺序从堆里面输出前k个即可
func topKFrequent(nums []int, k int) []int {
    hMap := map[int]int{}
    for _, v := range nums {
        hMap[v]++
    }

	h := &IntHeap{}
	heap.Init(h)
    i := 0
	for key, value := range hMap {
		heap.Push(h, [2]int{key, value})
        i++

        // 小优化点:将堆大小控制在k
        if i > k {
            heap.Pop(h)
        }
	}

    result := make([]int, k)
    for ; k > 0; k-- {
        ele := heap.Pop(h).([2]int)
        result[k - 1] = ele[0]
    }

    return result
}
posted @ 2020-07-21 19:33  Cenyol  阅读(97)  评论(0编辑  收藏  举报