第五章 栈与队列
239.滑动窗口最大值
主要思路:
单调队列:维护一个从左到右严格递减的数组
若当前值
大于队列尾部索引对应值
,for
弹出后追加值
若队首索引小于当前队列维护范围,丢弃
func maxSlidingWindow(nums []int, k int) []int {
n := len(nums)
res := make([]int, 0, n-k+1)
queue := []int{}
for i, val := range nums {
for len(queue) > 0 && val >= nums[queue[len(queue)-1]] {
queue = queue[:len(queue)-1]
}
queue = append(queue, i)
if queue[0] <= i-k {
queue = queue[1:]
}
if i >= k - 1 {
res = append(res, nums[queue[0]])
}
}
return res
}
347.前K个高频元素
文章详解
go语言,使用堆之前,需要定义底层数组,实现heap.Interface接口的五个函数
在实现Push()
和Pop()
的时候,需要使用指针接收。因为在修改切片长度时,可能会导致切片的引用发生改变。
type Iheap [][2]int
func (h Iheap) Len() int {
return len(h)
}
func (h Iheap) Less(i, j int) bool {
return h[i][1] < h[j][1]
}
func (h Iheap) Swap(i, j int) {
h[i], h[j] = h[j], h[i]
}
func (h *Iheap) Push(x interface{}) {
*h = append(*h, x.([2]int))
}
func (h *Iheap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[:n-1]
return x
}
主要思路:map记录数据及出现次数,小顶堆对次数排序,只保留前k大元素,最后逆向输出
func topKFrequent(nums []int, k int) []int {
count := map[int]int{}
for _, val := range nums {
count[val]++
}
h := &Iheap{}
heap.Init(h)
for key, val := range count {
heap.Push(h, [2]int{key, val})
if h.Len() > k {
heap.Pop(h)
}
}
res := make([]int, k)
for i := 0; i < k; i++ {
res[k-i-1] = heap.Pop(h).([2]int)[0]
}
return res
}
总结
看大佬们的题解和代码好清晰,慢慢进步吧