首页 > 其他分享 >[代码随想录]Day11-栈与队列part03

[代码随想录]Day11-栈与队列part03

时间:2023-08-07 21:47:19浏览次数:69  
标签:nums int part03 随想录 queue Day11 func ans MyQueue

题目:239. 滑动窗口最大值

思路:

239.滑动窗口最大值.gif

说实话这题真不能说是困难题,麻烦是麻烦点但是比较容易实现。

维护一个单调队列,队列内是由大到小排序(数组内的顺序是由小到大的),每次移动都会进行两次判断:

  1. 如果前面去掉的数就是队列的首部,那么就要把首部移除
  2. 如果后面添加的数比队尾的元素要大就删除队尾,重复2直到成为它队首或者遇到一个比它大的数

在上面两个规则的约束下得到的单调队列就是由大到小排序,数组内的顺序是由小到大的。

下面代码中把所有的判断都写在了方法里。

代码:

type MyQueue struct {
    queue []int
    lens int
}

func (m *MyQueue) Front() int {
    return m.queue[0]
}

func (m *MyQueue) Back() int {
    return m.queue[m.lens-1]
}

func (m *MyQueue) Empty() bool {
    return m.lens == 0
}

func (m *MyQueue) Push(val int) { // 后面加上
    for !m.Empty() && val > m.Back() {
        m.queue = m.queue[:m.lens-1]
        m.lens--
    }
    m.queue = append(m.queue, val)
    m.lens++
}

func (m *MyQueue) Pop(val int) { // 前面去掉
    if !m.Empty() && val == m.Front() {
        m.queue = m.queue[1:]
        m.lens--
    }
}

func maxSlidingWindow(nums []int, k int) []int {
    res := []int{}
    queue := new(MyQueue)
    for i := 0; i < k; i++ {
        queue.Push(nums[i])
    }
    res = append(res, queue.Front()) // 前k个数的最大值
    for i := k; i < len(nums); i++ {
        // 滑动窗口移除最前面的元素
        queue.Pop(nums[i-k])
        // 滑动窗口添加最后面的元素
        queue.Push(nums[i])
        // 记录最大值
        res = append(res, queue.Front())
    }
    return res
}

参考:

代码随想录

题目:347. 前 K 个高频元素

思路:

一个是两个哈希,一个是堆,之后再详细说。

代码1:

func topKFrequent(nums []int, k int) []int {
	ans :=make([]int,0)
	mapHash:=map[int]int{}
	for _,v:=range nums{
		//利用哈希表将元素和出现次数放入hash表中
		mapHash[v]++
	}
	for key,_:=range mapHash{
		//将哈希表里面的key存入ans切片中
		ans =append(ans,key)
	}
	//核心思想,对切片进行排序
	//可以不用包函数,自己实现快速排序
	//这个对ans nums中出现的数字进行排序,排序的规则是按照出现次数由高到低排序
	sort.Slice(ans,func(a,b int)bool {return mapHash[ans[a]]>mapHash[ans[b]]})
	//最后输出的时候就是输出前三个就行
	return ans[:k]
}

代码2:

//方法一:小顶堆
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
}

参考:

代码随想录

标签:nums,int,part03,随想录,queue,Day11,func,ans,MyQueue
From: https://www.cnblogs.com/wtcsky/p/17612778.html

相关文章

  • 代码随想录算法训练营第十一天| 20. 有效的括号 1047. 删除字符串中的所有相邻重复项
    20.有效的括号    卡哥建议:讲完了栈实现队列,队列实现栈,接下来就是栈的经典应用了。 大家先自己思考一下 有哪些不匹配的场景,在看视频 我讲的都有哪些场景,落实到代码其实就容易很多了。   题目链接/文章讲解/视频讲解:https://programmercarl.com/0020.%E6%9C%8......
  • 代码随想录算法训练营第七天|力扣334.反转字符串、力扣541.反转字符串II、剑指offer05
    字符串反转字符串(力扣344.)如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。毕竟面试官一定不是考察你对库函数的熟悉程度,如果使用python和java的同学更需要注意这一点,因为python、java提供的库函数十分丰富。如果库函数仅仅是解题过程中的一小部分,并且......
  • 代码随想录-字符串-c++总结
    关于字符串string一些库函数的使用,不太熟悉,导致开始做的时候比较磕磕绊绊主要用到了<algorithm>中的reverse,以及string的resize,substr,erase等,在这贴一个C++字符串(string)常用操作总结-知乎(zhihu.com)C++的string库用法总结-知乎(zhihu.com)反转字符串||中,每2k个字符进......
  • [代码随想录]Day10-栈与队列part02
    题目:20.有效的括号思路:很简单的一个栈的题目:如果是左括号就存如果是右括号就和栈顶的匹配匹配失败就返回false匹配成功就删除栈顶元素如果结束后是空就说明匹配完成这里需要注意的一个点是可以用map来代替过多的ifelse,希望能学会!代码:varpairs=map[byte]byte{......
  • 代码随想录算法训练营第四十六天| 84.柱状图中最大的矩形
     84.柱状图中最大的矩形要求:有多个矩形,要求返回可能勾勒出的最大矩形思路:寻找右边第一个小于当前节点的index寻找左边第一个小于当前节点的index 右边:累加的方式,如果当前节点小于,那么判读后放进去左边,放进去了之后,当前节点后一个,就是左边最小的代码:1//要求:和相......
  • 初学C语言day11--文件IO及文件操作
    C语言文件IO文件的分类:文本文件:人能看得懂的文件,存储的是数据ASCII码的二进制'2''5''5'505353二进制文件:人看不懂,存储的是数据的补码25511111111文件IO:FILE*fopen(constchar*path,constchar*mode);功能:打开或创建文件path:文件的路径如果是相对路径,会默认......
  • 代码随想录算法训练营第十天| 232.用栈实现队列 225. 用队列实现栈
    232.用栈实现队列   卡哥建议:大家可以先看视频,了解一下模拟的过程,然后写代码会轻松很多。  题目链接/文章讲解/视频讲解:https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.html   做题思路:   记住栈和队列的......
  • [代码随想录]Day09-栈与队列part01
    题目:232.用栈实现队列思路:因为go没有栈和队列的类型,直接自己写就行了。比较简单的实现,具体看代码中的注释。代码:typeMyQueuestruct{numbers[]int}funcConstructor()MyQueue{returnMyQueue{numbers:[]int{}}}func(this*MyQueue)Push(xint){......
  • 代码随想录算法训练营第六天|力扣454.四数相加II、力扣383.赎金信、力扣15.三数之和、
    四数相加II(力扣454.)前两个数组的值直接遍历,并将和存入map中,key为和,value为出现次数后两个数组再次遍历,在map中寻找是否存在0-(c+d),若存在,count+=valuefor(a:A){//遍历ABfor(b:B){map[a+b]++;}}//insert操作for(c:C){for(d:D){target=0-(c+d);if(map.containsKey(t......
  • 代码随想录算法训练营第四十五天| 503.下一个更大元素II 42. 接雨水
    503.下一个更大元素II 要求:数组是环,需要找到下一个最大的元素思路1:先作为直线遍历,然后没有的节点,放到首部,再找比他大的节点注意:头节点代码:1//要求:返回循环数组中下一个更大的数字步数2//思路:先不循环遍历,3//然后对每个-1节点,以他为起始,放到数组的开头,计算有几......