【每日刷题】栈与队列-LC394、LC347、LC215

题外话:感觉脑子没长到栈这块…最近刷栈的题都好难啊…哭哭…坚持坚持!多刷几遍就好了!!

1. LC394.字符串解码

题目链接

先说数据结构。
维护两个栈:一个栈存之前的字符串,另一个栈存之后的字符串的重复次数(数字)
维护两个变量:res表示目前遍历到的字符组成的字符串,k表示遍历到的数字组成的数字

工作原理:
最开始的字符串为""。
遇到字符时:存到res里。
遇到数字时:存到k里。
遇到左括号:把左括号前面的字符串,以及左括号内要循环的次数(数字),分别入栈,即res和k入栈。然后res和k重置。
遇到右括号:说明此时的res为最小单位,将数字栈里的栈顶元素出栈,这个数字将是res循环的次数。然后将字符串栈里的栈顶元素出栈,这个元素是括号前的字符串,后面需要拼接res。拼接后,形成新的res。不入栈。等遇到左括号再入栈。

例:
3[a2[c]] 看成 ""3[a2[c]]

图片版:
在这里插入图片描述

文字版:
在这里插入图片描述
代码
注意当字符是数字字符的处理逻辑。

  1. c >= '0' && c <= '9' 来确定当前字符是不是数字字符
  2. c-'0' 得到当前字符代表的数字,将字符转为数字
  3. k = k * 10 + (c-'0'); 这个也很妙。如果k已经有数字了,例如k已经等于12了,这时又遍历到3,那么就是k*10再加上当前的数字,123。
class Solution {public String decodeString(String s) {int k = 0;StringBuilder res = new StringBuilder();Stack<StringBuilder> stack_Res = new Stack<>();Stack<Integer> stack_K = new Stack<>();for (char c : s.toCharArray()){if (c >= '0' && c <= '9'){k = k * 10 + (c-'0');}else if (c == '['){stack_Res.push(res);stack_K.push(k);res = new StringBuilder();k = 0;}else if (c == ']'){int count = stack_K.pop();StringBuilder temp = new StringBuilder();for (int i=0; i<count; i++){temp.append(res);}res = stack_Res.pop().append(temp);}else{res.append(c);}}return res.toString();}
}

2. LC347、前K个高频元素

题目链接
解法一:

  1. 遍历一遍,建立哈希表存储数字与出现频次的映射。
  2. 维护一个元素数目为k的小顶堆。(堆中存放的是元素,但是priority queue可以按照自定义顺序排序,自定义顺序为:元素的频次)。
  3. 当有新元素来的时候,与堆顶元素作比较,若频次比堆顶元素大,则该元素应放到前k个高频元素中,所以堆顶元素出队列,该元素加队列。堆会自动按定义顺序排序。
  4. 最终堆中的元素就是前K个高频元素。

时间复杂度:
建立哈希表:n;小顶堆本身维护:logk;遍历哈希,维护小顶堆:nlogk;遍历堆存进数组:k
所以整体时间复杂度为O(nlogk)

空间复杂度:
哈希表:n,小顶堆:k。
所以整体空间复杂度为O(n)

class Solution {public int[] topKFrequent(int[] nums, int k) {//建立哈希表维护 数值与频次 的键值对Map<Integer, Integer> map = new HashMap<>();for (int i : nums){if (map.containsKey(i)){map.put(i, map.get(i)+1);}else{map.put(i, 1);}}//定义PriorityQueue存放前k个高频元素PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){@Overridepublic int compare(Integer a, Integer b){return (map.get(a) - map.get(b));}});//遍历map,更新堆for (Integer key: map.keySet()){if (queue.size() < k){queue.offer(key);}else{if (map.get(key) > map.get(queue.peek())){queue.poll();queue.offer(key);}}}//输出堆元素int[] array = new int[k];for (int i=0; i<k; i++){array[i] = queue.poll();}return array;}
}

解法二:

  1. 遍历一遍,建立哈希表存储数字与出现频次的映射。
  2. 将Map.entrySet<>存放进list,list排序,按照自定义规则排序(按照频次,即value值从大到小排序)
  3. 获取list中前k个元素的key值

时间复杂度:
建立哈希表:n;放进list:n;sort方法排序:nlogn;遍历堆存进数组:k
所以整体时间复杂度为O(nlogn)

空间复杂度:
O(n)

class Solution {public int[] topKFrequent(int[] nums, int k) {//建立哈希表维护 数值与频次 的键值对Map<Integer, Integer> map = new HashMap<>();for (int i : nums){if (map.containsKey(i)){map.put(i, map.get(i)+1);}else{map.put(i, 1);}}//将entryset放进list,对list进行排序List<Map.Entry<Integer, Integer>> list = new ArrayList<>();for (Map.Entry<Integer, Integer> entry: map.entrySet()){list.add(entry);}Collections.sort(list, (list1, list2) -> list2.getValue() - list1.getValue());//获取前k个值int[] array = new int[k];for (int i=0; i<k; i++){array[i] = list.get(i).getKey();}return array;}
}

3. LC215.数组中的第k个最大元素

题目链接

用优先级队列方法做。
PriorityQueue,peek()方法返回的是堆顶元素,poll()方法移除的也是堆顶元素,offer()方法把元素插入队列末尾,队列会根据自定义实现排序。
所以我们考虑使用大顶堆还是小顶堆呢?
因为poll和peak针对的是堆顶元素,所以我们每次新来一个元素若想加入堆,都必须要移除堆顶的元素。如果是大顶堆的话,堆顶是最大的元素,但显然最大的元素不能被移除。所以我们要用小顶堆。若新来的元素比堆顶的大,则移除堆顶元素,把新元素加入进来。这样可以实现最后得到的大顶堆是前k个最大元素。堆顶就是第k个最大元素

代码
注意:

  1. 优先级队列的定义,还是要熟悉,尤其是里面的comparator怎么写
  2. 只有当新元素大于堆顶,而非大于等于时,才将新元素加入进来。比如考虑655,5是第二大元素,无论哪个5都是第二大元素,但如果两个5都加到堆里来的话,那堆里就有三个元素了,就成前3大元素了。所以加入堆的条件不能是等于。
  3. 基本类型转包装类,包装类转基本类型,必须熟记。
class Solution {public int findKthLargest(int[] nums, int k) {PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){public int compare(Integer a, Integer b){return a.intValue() - b.intValue();}});int index = 0;for (int i: nums){if (index < k){queue.offer(Integer.valueOf(i));}else{if (i > queue.peek()){queue.poll();queue.offer(Integer.valueOf(i));}}index++;}return queue.peek();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云轻量服务器流量用完了怎么办?停机吗?

腾讯云轻量服务器流量用完了怎么办&#xff1f;超额流量另外支付流量费&#xff0c;流量价格为0.8元/GB&#xff0c;会自动扣你的腾讯云余额&#xff0c;如果你的腾讯云账号余额不足&#xff0c;那么你的轻量应用服务器会面临停机&#xff0c;停机后外网无法访问&#xff0c;继…

探索React中的类组件和函数组件

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

类与对象-对象特性

师从黑马程序员 对象的初始化和清理 构造函数和析构函数 用于完成对象的初始化和清理工作 如果我们不提供构造和析构&#xff0c;编译器会提供编译器提供的构造函数和析构函数是空实现 构造函数&#xff1a;主要用于创建对象时为对象的成员属性赋值&#xff0c;构造函数由编…

每日学习笔记:C++ STL 的Vector

Vector定义 Vector的大小与容量 Vector的函数 操作注意事项 Vector当作C数组 vector<bool>

瑞芯微第二代8nm高性能AIOT平台 RK3576 详细介绍

RK3576处理器 RK3576瑞芯微第二代8nm高性能AIOT平台&#xff0c;它集成了独立的6TOPS&#xff08;Tera Operations Per Second&#xff0c;每秒万亿次操作&#xff09;NPU&#xff08;神经网络处理单元&#xff09;&#xff0c;用于处理人工智能相关的任务。此外&#xff0c;R…

【C语言】深入理解指针(进阶篇)

一、数组名的理解 数组名就是地址&#xff0c;而且是数组首元素的地址。 任务&#xff1a;运行以下代码&#xff0c;看数组名是否是地址。 #include <stdio.h> int main() {int arr[] { 1,2,3,4,5,6,7,8,9,0 };printf("&arr[0] %p\n", &arr[0]);pri…

数据结构——算法的空间复杂度

【本节内容】 1.空间复杂度 2.常见空间复杂度 1.空间复杂度 空间复杂度也是一个数学表达式&#xff0c;是对一个算法在运行过程中临时占用额外存储空间大小的量度。 空间复杂度不是程序占用了多少bytes的空间&#xff0c;因为这个也没太大意义&#xff0c;所以空间复杂度算…

动态规划课堂4-----子数组系列

目录 引入&#xff1a; 例题1&#xff1a;最大子数组和 例题2&#xff1a;环形子数组的最大和 例题3&#xff1a;乘积最大子数组 例题4&#xff1a;乘积为正数的最长子数组 总结&#xff1a; 结语&#xff1a; 引入&#xff1a; 在动态规划&#xff08;DP&#xff09;子…

java中移位<< >> <<< |数据类型转换

移位 x64转换二进制&#xff1a;100 0000 左移2位 &#xff1a; 1000 0000 0 对应十进制 i 256 >>右移 <<左移 >>无符号位右移 关于右移一位相当于整除2 数据类型及其转换 基本数据类型&#xff0c;数据类型范围 byte(-128~127)&#xff08;-2^7~2…

【开源】SpringBoot框架开发教学资源共享平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 类图设计3.3 数据库设计3.3.1 课程档案表3.3.2 课程资源表3.3.3 课程作业表3.3.4 课程评价表 四、系统展…

mysql如何开启手动提交事务

在mysql中&#xff0c;有一个变量autocommit&#xff0c;表示自动提交&#xff0c;默认为1&#xff0c;表示开启自动提交。通过以下命令查询 select autocommit;当autocommit为1时&#xff0c;任何一条sql语句都是一个事务&#xff0c;执行完由mysql自动提交。如果想自己决定什…

Java 抽象类和接口

登神长阶 第三阶 抽象类和接口 &#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&#x1f340;&…

LVS负载均衡集群基础概念

目录 一、集群 1、集群概述 1.1 什么是集群 1.2 集群系统扩展方式 1.2.1 Scale UP&#xff08;纵向扩展&#xff09; 1.2.2 Scale OUT&#xff08;横向扩展&#xff09; 1.2.3 区别 1.3 分布式系统 1.4 分布式与集群 1.5 集群设计原则 1.6 集群设计实现 1.6.1 基础…

存储引擎的简介

简介&#xff1a; 1.在mysql存储引擎可以说就是指表的类型&#xff0c;可以称为表处理器&#xff0c;以表的形式存储。 2.他的功能就是接收上层传下来的指令&#xff0c;然后对表中的数据进行提取写入操作。 目的&#xff1a; 为了管理方便&#xff0c;我们把连接管理&#xf…

并查集(蓝桥杯 C++ 题目 代码 注解)

目录 介绍&#xff1a; 模板&#xff1a; 题目一&#xff08;合根植物&#xff09;&#xff1a; 代码&#xff1a; 题目二&#xff08;蓝桥幼儿园&#xff09;&#xff1a; 代码&#xff1a; 题目三&#xff08;小猪存钱罐&#xff09;&#xff1a; 代码&#xff1a; …

AWS的CISO:GenAI只是一个工具,不是万能钥匙

根据CrowdStrike的年度全球威胁报告,尽管研究人员预计人工智能将放大对防御者和攻击者的影响,但威胁参与者在其行动中使用人工智能的程度有限。该公司上个月在报告中表示:“在整个2023年,很少观察到GenAI支持恶意计算机网络运营的开发和/或执行。” 对于GenAI在网络安全中的…

《vtk9 book》 官方web版 第3章 - 计算机图形基础 (3 / 6)

3.8 演员几何 我们已经看到了光照属性如何控制演员的外观&#xff0c;以及相机如何结合变换矩阵将演员投影到图像平面上。剩下的是定义演员的几何形状&#xff0c;以及如何将其定位在世界坐标系中。 建模 计算机图形学研究中的一个重要主题是建模或表示物体的几何形状。…

贪心算法(蓝桥杯 C++ 题目 代表 注解)

介绍&#xff1a; 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望最终能够得到全局最好或最优的结果的算法。它通常用来解决一些最优化问题&#xff0c;如最小生…

扩展CArray类,增加Contain函数

CArray不包含查找类的函数&#xff0c;使用不便。考虑扩展CArray类&#xff0c;增加Contain函数&#xff0c;通过回调函数暴露数组元素的比较方法&#xff0c;由外部定义。该方法相对重载数组元素的“”符号更加灵活&#xff0c;可以根据需要配置不同的回调函数进行比较 //类型…

电脑解锁后黑屏有鼠标--亲测!!不需要重装系统!!

问题&#xff1a;上周电脑黑屏&#xff0c;只有鼠标&#xff0c;鼠标还不能右键&#xff01;&#xff01; 中招&#xff1a;win10系统最新版火绒安全 &#xff0c;那你有概率获得开机黑屏套餐一份。 原因是&#xff1a;火绒把我们的explorer删除了导致黑屏&#xff0c;这个文…