-
239滑动窗口最大值
- 代码随想录 (programmercarl.com)
-
第一印象
- 可以利用有序的栈,栈顶就是滑动窗口范围内的最大值,窗口本次变动滑过的值用-k来求,如果等于最大值,则pop。每次移动时比较栈顶并压入即可。
-
遇到错误
-
func maxSlidingWindow(nums []int, k int) []int { st := []int{} win := make([]int,k) win = nums[0:k] for _, i:=range win { if len(st)==0 { st = append(st, i) continue } else if i >= st[len(st)-1] { st=append(st, i) } } ans := make([]int,0) ans = append(ans, st[len(st)-1]) for j:=k;j<len(nums);j++ { if nums[j-k] == st[len(st)-1] { if len(st)-1==0 { st = make([]int,0) } else { st = st[:len(st)-1] } } if len(st)==0 || nums[j]>=st[len(st)-1] { st = append(st, nums[j]) } ans = append(ans, st[len(st)-1]) } return ans } - 错误原因:只维护了第一个值与最大值,窗口元素不完整。
- 解决办法:维护整个窗口的单调队列
-
解题代码
-
// 封装单调队列的方式解题 type MyQueue struct { queue []int } func NewMyQueue() *MyQueue { return &MyQueue{ queue: make([]int, 0), } } func (m *MyQueue) Front() int { return m.queue[0] } func (m *MyQueue) Back() int { return m.queue[len(m.queue)-1] } func (m *MyQueue) Empty() bool { return len(m.queue) == 0 } func (m *MyQueue) Push(val int) { for !m.Empty() && val > m.Back() { m.queue = m.queue[:len(m.queue)-1] } m.queue = append(m.queue, val) } func (m *MyQueue) Pop(val int) { if !m.Empty() && val == m.Front() { m.queue = m.queue[1:] } } func maxSlidingWindow(nums []int, k int) []int { queue := NewMyQueue() length := len(nums) res := make([]int, 0) // 先将前k个元素放入队列 for i := 0; i < k; i++ { queue.Push(nums[i]) } // 记录前k个元素的最大值 res = append(res, queue.Front()) for i := k; i < length; i++ { // 滑动窗口移除最前面的元素 queue.Pop(nums[i-k]) // 滑动窗口添加最后面的元素 queue.Push(nums[i]) // 记录最大值 res = append(res, queue.Front()) } return res } -
347前k个高频元素
- 代码随想录 (programmercarl.com)
-
第一印象
- 可以利用kv形式的容器存储元素及其频率,然后还需要排序。
-
解题代码
Go基础:heap的介绍与使用 - 知乎 (zhihu.com)
//方法一:小顶堆
func topKFrequent(nums []int, k int) []int {
map_num:=map[int]int{}
//记录每个元素出现的次数
for _,item:=range nums{
map_num[item]++
}
h:=&IHeap{}
heap.Init(h)
//所有元素入堆,堆的长度为k
for key,value:=range map_num{
heap.Push(h,[2]int{key,value})
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
}
//构建小顶堆
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[0:n-1]
return x
}
//方法二:利用O(nlogn)排序
func topKFrequent(nums []int, k int) []int {
ans:=[]int{}
map_num:=map[int]int{}
for _,item:=range nums {
map_num[item]++
}
for key,_:=range map_num{
ans=append(ans,key)
}
//核心思想:排序
//可以不用包函数,自己实现快排
sort.Slice(ans,func (a,b int)bool{
return map_num[ans[a]]>map_num[ans[b]]
})
return ans[:k]
}