05栈和队列/代码随想录

六、栈和队列

6.1数据结构的应用
  1. 用栈实现队列

    力扣232

    在这里插入图片描述

    很简单,添加的时候正常加在弹入栈,删除的时候把元素放到弹出栈,直接调用java集合实现的Stack

    class MyQueue {Stack<Integer> stackIn;Stack<Integer> stackout;public MyQueue() {stackIn = new Stack<>();stackout = new Stack<>();}public void push(int x) {stackIn.push(x);}public int pop() {dumpstackIn();return stackout.pop();}public int peek() {dumpstackIn();return stackout.peek();}public boolean empty() {return stackIn.isEmpty()&&stackout.isEmpty();}private void dumpstackIn() {if (!stackout.isEmpty()) return;while (!stackIn.isEmpty()) {stackout.push(stackIn.pop());}}
    }
    
  2. 用队列实现栈

    力扣225

    在这里插入图片描述

    很经典的题目,可以实现两个队列因为栈是先进后出,所以我们可以删除或者增加元素的时候把所有元素放到另一个队列中,然后再把数据追加上去,这样另一个增加或者删除就正常了。

    class MyStack {Queue<Integer> queueIn = new ArrayDeque<>();Queue<Integer> queueOut = new ArrayDeque<>();public MyStack() { }public void push(int x) {queueIn.offer(x);}public int pop() {while (queueIn.size() > 1) {queueOut.offer(queueIn.poll());}int res = queueIn.poll();Queue<Integer> temp = queueIn;queueIn = queueOut;queueOut = temp;return res;}public int top() {while (queueIn.size() > 1) {queueOut.offer(queueIn.poll());}int res = queueIn.poll();Queue<Integer> temp = queueIn;queueIn = queueOut;queueOut = temp;queueIn.offer(res);return res;}public boolean empty() {return queueIn.isEmpty();}
    }
    
    • 单个队列,就是正常增加元素,删除的时候把要删除的元素,全部拿出来放到要删除元素的后面
    class MyStack {Queue<Integer> queue = new ArrayDeque<>();public MyStack() { }public void push(int x) {queue.offer(x);int size = queue.size();while (size - 1 > 0) {queue.offer(queue.poll());size--;}}public int pop() {return queue.poll();}public int top() {return queue.peek();}public boolean empty() {return queue.isEmpty();}
    }
    
6.2栈的应用
  1. 有效的括号

    力扣20

    在这里插入图片描述

    就是为栈量身定做的,没碰到一个符号的前半部分就把后半部分放到栈中,到后半部分开始的时候,正常弹栈匹配即可

    class Solution {public boolean isValid(String s) {Stack<Character> newStack = new Stack<>();for (char i : s.toCharArray()) {switch (i) {case '(':newStack.push(')');break;case '{':newStack.push('}');break;case '[':newStack.push(']');break;default:if (newStack.isEmpty() || newStack.pop() != i) {return false;}}}return newStack.isEmpty();}
    }
    
  2. 删除字符串中所有重复相邻重复项

    力扣1047

    在这里插入图片描述

    其实这题我觉得用不用无所谓,题本身比较简单,只要碰到重复元素即可,开辟一个空间,添加的元素判断是否与前一项相等,如果相等就全部删除,但是第一眼最方便的还是栈,数组需要通过下标需要考虑边界,没有栈的方法来的方便

    class Solution {public String removeDuplicates(String s) {Stack<Character> newStack = new Stack<>();for(char i : s.toCharArray()) {if (!newStack.isEmpty() && newStack.peek() == i) {newStack.pop();continue;}else {newStack.push(i);}}// 将栈中的字符转换为字符串StringBuilder result = new StringBuilder();for (char c : newStack) {result.append(c);}return result.toString();}
    }
    
  3. 逆波兰表达式求值

    力扣150

    在这里插入图片描述

    其实理解了题目很好做,计算机更喜欢这种类似于数逆序遍历的排序,不需要考虑括号什么的 a b + c *就知道是(a+b)*c,不需要去考虑优先级。这种只涉及一个方向的删除增加很适合用栈,所以只要遍历tokens,碰到数字就放入栈,然后碰到运算符就计算,记得把结果放入栈。也要记得减法和除法的特殊,先pop的是除数和减数

    class Solution {public int evalRPN(String[] tokens) {Stack<Integer> newStack = new Stack();for (String s : tokens) {switch (s) {case "+":newStack.push(newStack.pop() + newStack.pop());break;case "-":int b = newStack.pop();int a = newStack.pop();newStack.push(a - b);break;case "/":b = newStack.pop();a = newStack.pop();newStack.push(a / b);break;case "*":newStack.push(newStack.pop() * newStack.pop());break;default:newStack.push(Integer.parseInt(s));}}return newStack.pop();}
    }
    
6.3堆的应用
  1. 滑动窗口最大值

    力扣239

    在这里插入图片描述

    1. 使用大顶堆,我们知道大顶堆会自动排序,时间复杂度度为O(logn),但是要注意大顶堆是会打乱顺序的,但是最大的元素始终是在最前面的,我们只要循环判断,前面的元素在不在滑动区间范围内即可,这样就不会出现问题,也就是说这个滑动区间,可能并不是一直是长度为3,但是会保证不该在滑动区间范围内的元素不会影响该滑动区间。再次强调弹出滑动区间的判断第一个最大元素是不是在滑动区间内即可。比如12323 k为3 此时滑动区间为312(大顶堆是完全二叉树,所以这里12不会变化顺序,但是这里也不重要,因为最大的元素一定在最前面,那么后面的元素就不会有影响,只要最大的不在滑动区间内就一定会被删除,这几个方法就保证了不会出问题),最大为3再往下3221(至于为什么是321,这是堆的性质,不清楚的话,我可以下期出一篇文章讲),最大还是3。

      import java.util.*;public class Solution {public int[] maxSlidingWindow(int[] nums, int k) {// 结果数组的初始化int n = nums.length;int[] result = new int[n - k + 1];// 定义大顶堆,存储值和索引,按值降序排序PriorityQueue<int[]> maxHeap = new PriorityQueue<>((a, b) -> b[0] - a[0] // 按值降序);// 初始化堆,加入前 k 个元素for (int i = 0; i < k; i++) {maxHeap.offer(new int[]{nums[i], i});}// 第一个窗口的最大值result[0] = maxHeap.peek()[0];// 滑动窗口,从 k 到 nums.lengthfor (int i = k; i < n; i++) {// 加入新元素maxHeap.offer(new int[]{nums[i], i});// 移动窗口左边界,确保堆顶的索引在窗口内while (maxHeap.peek()[1] <= i - k) {maxHeap.poll();}// 记录当前窗口的最大值result[i - k + 1] = maxHeap.peek()[0];}return result;}
      }
      
    2. 单调队列(其实就是保持顺序的双端队列),用双端队列的原因就是因为可以前删后加

      单调队列是按照大小顺序排列的,其实在本题很多情况都是区间只有一个元素,因为只要出现新元素比尾元素大,那么就不断poll尾元素,while循环直到不行位置,可以发现,始终是保持数组顺序的。所以删除操作只要用if判断队首是不是不在区间内即可。具体细节参考如下

      import java.util.*;public class Solution {public int[] maxSlidingWindow(int[] nums, int k) {Deque<Integer> queue = new LinkedList<>();int n = nums.length;int[] result = new int[n - k + 1];// 如果新元素比队尾元素大,则删除队尾元素,不停的while循环,这样保证了滑动窗口不会被打乱// 这里初始化,不会有问题for (int i = 0; i < k; ++i) {while (!queue.isEmpty() && nums[i] >= nums[queue.peekLast()]) {queue.pollLast();}queue.offerLast(i);}result[0] = nums[queue.peekFirst()];// 因为是按照顺序排列的单调双端队列,首先要删除左边界外的元素,每次循环一次判断一次就好,因为是按照顺序排布的// 不用每次while循环,是真正的按照顺序排列,堆是有多条分支的,所以它会出现顺序打乱,所以堆是使用while循环的// 首先删除不在范围内的元素,但要保证滑动窗口不能为空,推荐把删除判断写在加入结果列表的前面for (int i = k; i < n; ++i) {while (!queue.isEmpty() && nums[i] >= nums[queue.peekLast()]) {queue.pollLast();}queue.offerLast(i);if (queue.peekFirst() <= i - k) {queue.pollFirst();}result[i - k + 1] = nums[queue.peekFirst()];}return result;}
      }
      
  2. 前k个高频元素

    力扣347

    在这里插入图片描述

    像这种统计次数的,一眼哈希表,后续就按照大小排列,取前k个就好,这里是使用工具类自己排序+stream优雅书写,思路明了,主要要把结果转换为int数组

    class Solution {public int[] topKFrequent(int[] nums, int k) {Map<Integer, Integer> count = new HashMap<>();// 统计每个数字的频率for (int num : nums) {count.put(num, count.getOrDefault(num, 0) + 1);}int[] result = count.entrySet().stream().sorted((a, b) -> b.getValue().compareTo(a.getValue())) .limit(k).mapToInt(Map.Entry::getKey)  // 转换为int类型,一个流只能终结一次.toArray();return result;}
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/8287.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

51c大模型~合集18

我自己的原文哦~ https://blog.51cto.com/whaosoft/11621494 #SpatialBot 空间大模型&#xff1a;上交、斯坦福、智源、北大、牛津、东大联合推出&#xff01; 大模型走向空间智能、具身智能之路&#xff01; 智源&#xff0c;斯坦福&#xff0c;北大&#xff0c;牛津&…

国外白帽故事 | 攻破大学数据库系统,暴露数千学生记录

引言 在这篇文章中&#xff0c;我将分享我是如何攻破一个大型大学解决方案门户服务器的&#xff0c;这个服务器服务于许多大学客户&#xff0c;并且涉及数千名学生的数据。 目标 这是一个由印度许多大学和学院使用的门户网站&#xff0c;用于管理学生记录、成绩单、出勤记录…

苍穹外卖05-Redis相关知识点

目录 什么是Redis&#xff1f; redis中的一些常用指令 value的5种常用数据类型 各种数据类型的特点 Redis中数据操作的常用命令 字符串类型常用命令&#xff1a; 哈希类型常用命令 列表操作命令 集合操作命令 有序集合操作命令 通用命令 在java中操作Redis 环境…

【MySQL】数据的增删查改

文章目录 1. 插入数据(Create)1.1 全列插入1.2 指定列插入1.3 多行数据插入1.4 插入否则更新1.5 替换 2. 读取数据(Retrieve)2.1 select列2.2 where条件2.3 结果排序2.4 筛选分页结果 3. 修改数据(Update)4. 删除数据(delete)4.1 删除数据4.2 截断表 5. 插入查询的结果6. 分组与…

【案例分享】借助 iSpring,创造客户真正欣赏的专业在线培训体验

Safety Bee Training是一家领先的认证在线学习提供商&#xff0c;专门提供职业健康、安全和环境项目。它也是中东和亚洲唯一一家提供经 NASP 等国际认证机构认可的课程的培训提供商。它已经培训了超过 28,000 名学习者&#xff0c;并且正在不断扩大其课程范围&#xff0c;以提供…

【连续多届检索,ACM出版】第四届大数据、人工智能与风险管理国际学术会议 (ICBAR 2024,11月15-17)--冬季主会场

第四届大数据、人工智能与风险管理国际学术会议 (ICBAR 2024)--冬季主会场 2024 4th International Conference on Big Data, Artificial Intelligence and Risk Management 会议官网&#xff1a;www.icbar.net 2024 4th International Conference on Big Data, Artificial I…

界面设计软件:10款设计师必备工具

UI界面设计软件是设计师们不可或缺的工具&#xff0c;它们提供了一系列功能和直观的操作界面&#xff0c;助力设计师迅速打造精美且用户友好的界面。面对众多UI设计软件&#xff0c;有的提供预设模板和图标库&#xff0c;有的更侧重于原型和交互设计。如何选择最适合自己的UI设…

TCP(上):成熟可靠的传输层协议

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! TCP&#xff08;传输控制协议&#xff09;是位于传输层的通信协议&#xff0c;是一种面向连接的、可靠的、基于字节流的传输层通信协议。主要负责在不可靠的网络环境中提供可靠的端到端字节流传输服务。TCP是…

如何在Windows中检查是否安装了GPU

文章目录 1. 系统设备管理器1.1 打开设备管理器1.2 查找显示适配器 2. 命令行工具2.1 打开命令提示符2.2 执行WMIC命令 3. DirectX诊断工具3.1 运行DirectX诊断工具3.2 查看显示信息 在Windows操作系统中&#xff0c;了解您的电脑是否配备了图形处理单元&#xff08;GPU&#x…

网络技术----wireshark抓包出现1500以上的大包原因分析

网络技术----wireshark抓包出现1500以上的大包原因分析 背景描述原因分析TSO&#xff08;TCP segment offload&#xff0c;TSO&#xff09;linux中关闭/开启TSO功能&#xff1a;其他类似TSO的机制 wireshark抓包来源 背景描述 我们在使用抓包工具的过程中&#xff0c;经常发现…

3.3 软件需求:面对对象分析模型

面对对象分析模型 1、对象2、面对对象的软件开发模型3、用例图建模基础3.1 用例图基本符号参与者用例系统执行关联 3.2 用例建模过程3.3 用例图初步3.4 用例图进阶关联Association泛化Inheritance包含Include扩展Extend示例 1、对象 在现实世界中有意义的&#xff0c;与所要解…

跑批为什么这么难

业务系统产生的明细数据通常要经过加工处理&#xff0c;按照一定逻辑计算成需要的结果&#xff0c;用以支持企业的经营活动。这类数据加工任务一般会有很多个&#xff0c;需要批量完成计算&#xff0c;在银行和保险行业常常被称为跑批&#xff0c;其它像石油、电力等行业也经常…

深⼊理解指针(3)【数组与指针】

目录 1. 数组名的理解 2. 使⽤指针访问数组 3. ⼀维数组传参的本质 4. 冒泡排序 5. ⼆级指针 6. 指针数组 7. 指针数组模拟⼆维数组 一 数组名的理解 由上图可知我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址…

ubuntu【桌面】 配置NAT模式固定IP

DHCP分配导致虚拟机IP老变&#xff0c;SSH老要重新配置&#xff0c;设成静态方便些 一、设NAT模式 1、设为NAT模式 2、看模式对应的虚拟网卡 - VMnet8 3、共享主机网卡网络到虚拟网卡 - VMnet8 二、为虚拟网卡设置静态IP 记住这个IP IP不要与网关重复 这里网关注意要与虚拟…

最强攻略密码 | 腾讯云双十一活动爆款直击底价

前言 每年双十一&#xff0c;腾讯云都会推出一系列的优惠活动&#xff0c;吸引着大量的消费者和开发者参与。作为国内领先的云计算服务商之一&#xff0c;腾讯云不仅提供强大的云计算基础设施服务&#xff0c;还涉及云存储、大数据分析、人工智能等多个领域&#xff0c;而双十…

c# 动态lambda实现二级过滤(多种参数类型)

效果 调用方法 实体类&#xff08;可以根据需求更换&#xff09; public class ToolStr50 {public bool isSelected { get; set; }public string toolStr1 { get; set; }public string toolStr2 { get; set; }public string toolStr3 { get; set; }public string toolStr4 { …

5万加购上线即断货,双11洗衣机品类打破增长难关

距离2024年双11结束仅剩最后几天。据网经社报告&#xff0c;目前各电商平台累计销售额已超8000亿元。 其中&#xff0c;家电品类已超1000亿元的销额位居前列&#xff0c;市场占有率达15.7%。天猫平台数据显示&#xff0c;预售日开售后1小时&#xff0c;大家电整体成交同比增长7…

[全网最细数据结构完整版]第六篇:3分钟带你吃透栈并模拟实现

目录 1->栈的概念和结构 1.1栈的概念 1.2栈的结构 2->栈的实现 2.1定义关于栈的结构体和各种函数 2.2栈的初始化 STInit 函数 2.3栈的销毁 STDestroy 函数 2.4栈的插入操作 STPush 函数 2.5栈的判断是否为空操作 STEmpty 函数 2.6栈的删除操作 STPop 函数 2.7…

Xfce桌面设置右键菜单:用右键打开VSCode

前言 AlmaLinux安装VSCode之后始终没有找到如何用右键菜单打开VSCode&#xff0c;比Windows麻烦多了。每次都需要先找到文件夹&#xff0c;然后用系统自带的Open In Terminal打开终端&#xff0c;再输入code .&#xff0c;才能够在当前文件夹中快速打开VSCode。那么&#xff0…

使用docker形式部署jumpserver

文章目录 前言一、背景二、使用步骤1.基础环境准备2.拉取镜像3.进行部署4.备份记录启动命令 前言 记录一下使用docker形式部署jumpserver服务的 一、背景 搭建一个jumpserver的堡垒机&#xff0c;但是发现之前是二进制文件部署的&#xff0c;会在物理机上部署污染环境&#x…