692.前K个高频单词

111 阅读1分钟

题目:
给定一个单词列表 words 和一个整数 k ,返回前 k **个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。

算法: 有排序和和heap两种实现。heap法注意: 1.less方法要根据单词频率和单词字典序 2.返回结果时要按照每次remove()的方法取。不能直接返回heap.Array数组。

func topKFrequent(words []string, k int) []string {
	wordsNum := make(map[string]int)
	for i := range words {
		wordsNum[words[i]] ++
	}

	heap := NewHeap(k)
	for word, num := range wordsNum {
		heap.Add(WordNum{word:word, num:num})
	}
	ans := make([]string, heap.N)
	// 逆序输出
	for i := heap.N; i > 0; i -- {
		wn := heap.remove()
		ans[i - 1] = wn.word
	}
	return ans
}

type WordNum struct {
	word string
	num int
}

type Heap struct{
	Array []WordNum
	N int
	Capacity int
}

func NewHeap(n int) *Heap{
	return &Heap{
		Array: make([]WordNum, 1),
		Capacity: n,
	}
}

func (h *Heap)Add(v WordNum){
	if h.N < h.Capacity {
		h.insert(v)
	} else if h.Array[1].num < v.num || (h.Array[1].num == v.num && h.Array[1].word > v.word ){
		h.insert(v)
		h.remove()
	}
}

func (h *Heap)insert(v WordNum){
	h.N ++
	h.Array = append(h.Array, v)
	h.swim(h.N)
}

// pop掉第一个元素
func (h *Heap) remove() WordNum{
	res := h.Array[1]
	h.Array[1], h.Array[h.N] = h.Array[h.N], h.Array[1]
	h.Array = h.Array[:h.N]
	h.N --
	h.sink(1)
	return res 
}

// less(i, parent)==true时,执行swim,节点i上浮,
func (h *Heap)sink(i int){
	child := 2 * i
	if child + 1 < len(h.Array) && h.less(child + 1, child) {
		child = child + 1
	}
	if child < len(h.Array) && h.less(child, i) {
		h.Array[i], h.Array[child] = h.Array[child], h.Array[i]
		h.sink(child)
	}
}


// less(i, parent)==true时,执行swim,节点i上浮,
func (h *Heap)swim(i int){
	// fmt.Println("swim", h.Array, i)
	parent := i / 2
	if 0 < parent && h.less(i, parent) {
		h.Array[i], h.Array[parent] = h.Array[parent], h.Array[i]
		h.swim(parent)
	}
}

func (h *Heap)less(i int, j int) bool {
	return h.Array[i].num < h.Array[j].num || h.characterless(i, j)
}

func (h *Heap)characterless(i int, j int) bool {
	return h.Array[i].num == h.Array[j].num && h.Array[i].word > h.Array[j].word
}

func (h *Heap)swap(i int, j int)  {
	h.Array[i], h.Array[j] = h.Array[j], h.Array[i]
}