二刷力扣--栈和队列
栈和队列
栈和队列基础(Python)
栈一种先进后出,队列先进后出。
Python中可以用list实现栈,用append()模拟入栈,用pop()模拟出栈。
也可以用list实现队列,但是效率较低,一般用collections.deque模拟(双端)队列。
5. 数据结构 — Python 3.11.5 文档
使用list进行栈的操作
stack = [3, 4, 5]
stack.append(6)
stack.append(7)
stack
[3, 4, 5, 6, 7]
stack.pop()
7
stack
[3, 4, 5, 6]
使用collections.dequez进行队列操作
from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry") # Terry arrives
queue.append("Graham") # Graham arrives
queue.popleft() # The first to arrive now leaves
'Eric'
queue.popleft() # The second to arrive now leaves
'John'
queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
232.用栈实现队列
#模拟
请你仅使用两个栈实现先入先出队列。
思路:
使用两个栈stackin和stackout分别进行入队和出队。
出队时,如果stackout为空,将stackin 倒入 stackout。
class MyQueue:def __init__(self):self.stackin = []self.stackout = []def push(self, x: int) -> None:self.stackin.append(x)def pop(self) -> int:if self.empty():return Noneif not self.stackout:while self.stackin:self.stackout.append(self.stackin.pop())return self.stackout.pop()def peek(self) -> int:res = self.pop()self.stackout.append(res)return resdef empty(self) -> bool:return not (self.stackin or self.stackout)
225. 用队列实现栈
#模拟
重点还是pop。使用队列弹出元素时,需要先把之前的n-1个元素弹出,才能弹出第n个元素。
所以这里先弹出n-1个元素并添加到队列末尾,然后第n个元素就到了队列的开头。
这题没法仿照232的思路。注意队列和栈的区别,栈是反转元素进出顺序的,两次反转则变为先进先出。而队列是保持顺序的,进出两次队列后顺序不变。
class MyStack:def __init__(self):self.que = deque()def push(self, x: int) -> None:self.que.append(x)def pop(self) -> int:if self.empty():return Nonefor i in range(len(self.que)-1):self.que.append(self.que.popleft())return self.que.popleft()def top(self) -> int:if self.empty():return Nonereturn self.que[-1]def empty(self) -> bool:return not self.que
20. 有效的括号
#栈
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串的括号是否有效。
栈的应用,使用栈来存储左括号,遇到右括号则弹出左括号进行匹配。
class Solution:def isValid(self, s: str) -> bool:stack = []d_k = {'(': ')', '{': '}', '[': ']'}for c in s:if c in d_k.keys():stack.append(c)else:if len(stack) == 0:return Falseleft = stack.pop()if c != d_k[left]:return Falsereturn len(stack) == 0
1047. 删除字符串中的所有相邻重复项
删除字符串的相邻重复字母,可以重复多次,直到没有没有相邻重复项。
#模拟 #栈
class Solution:def removeDuplicates(self, s: str) -> str:stack = []for c in s:if len(stack) > 0 and stack[-1] == c:stack.pop()else:stack.append(c)return "".join(stack)
150. 逆波兰表达式求值
#栈
逆波兰表达式又叫后缀表达式,运算符在操作数的后面,如:1 2 +
我们一般写的是中缀表达式,运算符在操作数的中间,如 : 1 + 2
输入: tokens = [“2”,“1”,“+”,“3”,“*”]
输出: 9
解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
借助栈,比较容易计算后缀表达式,遇到操作数就入栈,遇到运算符就弹出前面两个数,然后计算,并将计算结果入栈。
class Solution:def evalRPN(self, tokens: List[str]) -> int:stack = []res = 0for i in tokens:if i == '+' :a = stack.pop()b = stack.pop()stack.append(b+a)elif i == '-' :a = stack.pop()b = stack.pop()stack.append(b-a)elif i == '*' :a = stack.pop()b = stack.pop()stack.append(b*a)elif i == '/':a = stack.pop()b = stack.pop()stack.append(int(b/a))else :stack.append(int(i))return int(stack[-1])
看起来有点重复,可以简化一下:
class Solution:def evalRPN(self, tokens: List[str]) -> int:stack = []res = 0op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}for i in tokens:if i in op_map.keys():a = stack.pop() # 后b = stack.pop() # 前stack.append(op_map[i](b,a)) # 注意顺序 b op aelse :stack.append(int(i))return int(stack[-1])
239. 滑动窗口最大值
#单调队列 #队列
整体思路:希望有一个队列,在滑动窗口的时候,用push添加新的元素,用pop弹出被删除的元素,并且能直接获取队列的最大元素。
也就是说,我们希望实现一个队列存储可能成为窗口中最大值的元素。(称为单调队列)
- 为了方便添加和删除元素,使用双端队列存储数据。
self.queue = deque()
- 添加操作 push: 添加元素value时,如果队列末尾比value小,就
pop
掉,然后添加value。(也就意味着,队列中的元素都比新加入的value大。push操作很关键,保证了队列中的元素是单调递减的,因此后面可以用self.queue[0]
获取最大值)
def push(self, value):while self.queue and value > self.queue[-1]:# 队列末尾比value小则删除self.queue.pop() # pop,弹出队列末尾元素self.queue.append(value)
- 删除操作 pop:删除元素value时,如果value等于队首元素
que[0]
,则弹出队首popleft()
。
def pop(self, value):if self.queue and value == self.queue[0]:self.queue.popleft() # 弹出队首元素
获取最大值:
def front(self):return self.queue[0]
使用单调队列来解决滑动窗口最大值就比较简单了,不断地调用pop和push和 front。
class MyQueue:def __init__(self):self.queue = deque()# 删除value ,如果value 在队首则删除def pop(self, value):if self.queue and value == self.queue[0]:self.queue.popleft()# 添加value, valuea前面的比value小的都删除def push(self, value):while self.queue and value > self.queue[-1]:self.queue.pop()self.queue.append(value)def front(self):return self.queue[0]class Solution:def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:que = MyQueue()res = []for i in range(k):que.push(nums[i])res.append(que.front())for i in range(k, len(nums)):que.pop(nums[i-k])que.push(nums[i])res.append(que.front())return res
347.前 K 个高频元素
#优先级队列 #堆
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。
最容易想到的是用字典统计频率然后排序。
class Solution:def topKFrequent(self, nums: List[int], k: int) -> List[int]:mmap = Counter(nums)sort = sorted(zip(mmap.values(),mmap.keys()), reverse=True)res = []for i in range(k):res.append(sort[i][1])return res
用堆排序,我们只需要维护一个大小为k的堆(优先级队列)。
在Python中可以用heapq或queue.PriorityQueue 实现。
heapq — 堆队列算法 — Python 3.11.5 文档
queue — 一个同步的队列类 — Python 3.11.5 文档
使用heapq
import heapq
class Solution:def topKFrequent(self, nums: List[int], k: int) -> List[int]:#要统计元素出现频率map_ = Counter(nums)#对频率排序#定义一个小顶堆,大小为kpri_que = [] #小顶堆#用固定大小为k的小顶堆,扫描所有频率的数值for key, freq in map_.items():heapq.heappush(pri_que, (freq, key))if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为kheapq.heappop(pri_que)#找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组result = [0] * kfor i in range(k-1, -1, -1):result[i] = heapq.heappop(pri_que)[1]return result
使用PriorityQueue
class Solution:def topKFrequent(self, nums: List[int], k: int) -> List[int]:#要统计元素出现频率map_ = Counter(nums)#对频率排序from queue import PriorityQueue as PQpri_que = PQ(k+1) #优先级队列(相当于小根堆), 最多放k+1个元素#用固定大小为k的小顶堆,扫描所有频率的数值for key, freq in map_.items():pri_que.put((freq, key))if pri_que.qsize() > k:pri_que.get()print(pri_que.queue)#找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组result = [0] * kfor i in range(k-1, -1, -1):result[i] = pri_que.get()[1]return result
栈和队列小结
栈主要用来处理相邻匹配问题,队列可以处理滑动窗口的最值问题(单调队列,前k个最值问题(优先级队列/小根堆)。
python中栈可以用list实现,队列用colelctions.deque实现。
stack = [3, 4, 5]
stack.append(6)
stack.append(7)
stack.pop()
import collections
queue = collections.deque()
queue.append(1) # 入队
queue.append(2)
queue.popleft() # 出队
此外还用到了优先级队列(堆),默认实现的是小根堆(堆顶元素最小)。
import heapq
pri_que = [] #小顶堆
heapq.heappush(pri_que, 1) # 入队
heapq.heappush(pri_que, 2)
heapq.heappop(pri_que) # 出队
相关文章:
二刷力扣--栈和队列
栈和队列 栈和队列基础(Python) 栈一种先进后出,队列先进后出。 Python中可以用list实现栈,用append()模拟入栈,用pop()模拟出栈。 也可以用list实现队列,但是效率较低,一般用collections.deq…...

第六章 图 十、关键路径
开始顶点(源点): 在AOE网中仅有一个入度为0的顶点,称为开始顶点(源点),它表示整个工程的开始; 结束顶点(汇点): 也仅有一个出度为0的顶点,称为结束顶点(汇点)…...

Virtualbox固定存储硬盘转换为动态存储硬盘
现象 一开始分配固定存储过大,占了太多空间,现在想换成动态存储释放空闲空间。 解决 关闭虚拟机进入虚拟介质管理从使用的硬盘复制出一个动态存储硬盘在设置中把硬盘替换为副本硬盘 详细步骤参考: https://blog.csdn.net/qq_24033983/arti…...

【栈与队列面试题】有效的括号(动图演示)
leetcode20.括号匹配问题 前言: 💥🎈个人主页:Dream_Chaser~ 🎈💥 ✨✨刷题专栏:http://t.csdn.cn/UlvTc ⛳⛳本篇内容:力扣上栈与队列的面试OJ题目 目录 leetcode20.括号匹配问题 1.问题描…...

基于matlab实现的弹簧振动系统模型程序(动态模型)
完整代码: clear all; %System data m1.0; zeta0.01; omega01.0; Dt1.0; f01.0; x00.0; dotx00.0; xmaxsqrt(x0^2(dotx0/omega0)^2)min([0.5*abs(f0)*Dt/(m*omega0) f0/omega0^2]); omegadomega0*sqrt(1-zeta^2); dt00.1*pi/omega0; nstep500; a0.70; b0.…...

哨兵1号(Sentinel-1)SAR卫星介绍
1. 哥白尼计划 说起欧空局的哨兵1号,就不得不先说一下欧空局的“哥白尼计划”。 欧空局的哥白尼计划(Copernicus Programme)是欧空局与欧盟合作的一项极其重要的地球观测计划。该计划旨在提供免费开放的、可持续的地球观测数据,…...

[maven] scopes 管理 profile 测试覆盖率
[maven] scopes & 管理 & profile & 测试覆盖率 这里将一些其他的特性和测试覆盖率(主要是 jacoco) scopes maven 的 scope 主要就是用来限制和管理依赖的传递性,简单的说就是,每一个 scope 都有其对应的特性&…...
css网页打印字体设置
media print {font-family:"SimHei";color: #000;border-color: #000; }常用字符编码表 中文名英文名Unicode 编码黑体SimHeiSimHei微软雅黑Microsoft YaHei5FAE\8F6F\96C5\9ED1宋体SimSun\5B8B\4F53仿宋FangSong\4EFF\5B8B html5常用转义字符℃ 字符十…...

JAVA高级技术入门(单元测试,反射,注解,动态代理)
JAVA高级技术入门(单元测试,反射,注解,动态代理) 一、Junit单元测试二、反射1.认识反射,获取类概念:快速入门:获取Class对象的三种方式 2.1获取类的构造器2.2获取类的构造器的作用&a…...

uni-app 实现自定义按 A~Z 排序的通讯录(字母索引导航)
创建 convertPinyin.js 文件 convertPinyin.js 将下面的内容复制粘贴到其中 const pinyin (function() {let Pinyin function(ops) {this.initialize(ops);},options {checkPolyphone: false,charcase: "default"};Pinyin.fn Pinyin.prototype {init: functi…...

C++ PrimerPlus 复习 第一章 命令编译链接文件 make文件
第一章 命令编译链接文件 C 有什么呢?C 源代码文件后缀运行C过程可执行代码:编译语法:makeMakefile 基础语法编写完make只要和将要编译的文件放一起就行 然后在该目录使用make命令,就将自动运行;基础的Makefile版本 现…...

微信小程序——常用组件的属性介绍
常用的组件内容标签 text 文本组件类似于HTML中的span标签,是一个行内元素rich-text 富文本标签支持把HTML字符串渲染为WXML结构 text标签的基本使用 通过text组件的selectable属性,实现长按选中文本内容的效果。只有text标签支持长按选中效果&#x…...

【深度学习】 Python 和 NumPy 系列教程(廿七):Matplotlib详解:3、多子图和布局:散点矩阵图(Scatter Matrix Plot)
目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 3、多子图和布局 1. subplot()函数 2. subplots()函数 3. 散点矩阵图(Scatter Matrix Plot) 一、前言 Python是一种高级编程语言,由Guido van Rossum于…...

解决jupyter打开的默认路径问题
已经安装完anaconda,但是jupyter每一次打开的路径都不是自己想要的路径,可以在配置文件中修改jupyter打开的默认路径,具体步骤如下: 首先打开anaconda的命令行 如果有多个环境的,需要输入conda activate 环境名称以下命…...

Git 学习笔记
Git 学习笔记 Git 简介 Git 是一个 开源的分布式版本控制系统。 什么是版本控制? 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 什么是分布式版本控制系统? 介绍分布式版本控制系统前,有…...
【Qt】QGroundControl入门3:源码初探
1、源码目录 QGroundControl使用pro来管理工程,可以使用qmake来编译。同时还有CMakeLists.txt,应该可以使用cmake来编译,本人还没有尝试。 QGroundControl是跨平台的,支持android、win、linux、mac、ios系统,在QGCCommon.pri中可见关于跨平台编译的配置。 1.1 目录树 …...

腾讯mini项目-【指标监控服务重构】2023-07-31
今日已办 trace_id传播 关于如何使用 trace_id 创建 span 的思路 【暂未实现 & 测试】 调研 SpanProcessor 阅读源码的test 明日待办 根据 trace_id 创建 span,应该需要 parent span_id 才能有 trace 的树状 span 的关系...

Rust通用编程概念(3)
Rust通用编程概念 1.变量和可变性1.执行cargo run2.变量3.变量的可变性4.常量5.遮蔽5.1遮蔽与mut区别1.遮蔽2.mut 2.数据类型1.标量类型1.1整数类型1.2浮点数类型1.3数字运算1.4布尔类型1.5字符类型 2.复合类型2.1元组类型2.2数组类型1.访问数组2.无效的数组元素访问 3.函数3.1…...

学Python的漫画漫步进阶 -- 第四步
学Python的漫画漫步进阶 -- 第四步 四、运算符4.1 算术运算符4.2 比较运算符4.3 逻辑运算符4.4 位运算符4.5 赋值运算符4.6 运算符的优先级4.7 练一练4.8 运算符的总结全部16步完成后 ,后续就是介绍项目实战,请大家给予点赞、关注! 四、运算符…...

【LeetCode-中等题】18. 四数之和
文章目录 题目方法一:双指针(定2动2) 题目 方法一:双指针(定2动2) 这题可以参考【LeetCode-中等题】15. 三数之和 区别在于,三数之和只需要用一个for循环定住一个数,然后设置两个前…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...