代码随想录第十一天|150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

news/2024/10/27 10:27:54/

题目:150. 逆波兰表达式求值

根据逆波兰表示法,求表达式的值。

有效的运算符包括 +-*/。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明

  • 整数除法只保留整数部分。
  • 给定逆波兰表达式总是有效的,即表达式总能得出有效数值且不存在除数为 0 的情况。

解题思路

逆波兰表达式的特点是操作数在前,运算符在后,计算时从左到右扫描,并在遇到运算符时进行计算。因此可以使用栈来辅助计算:

  1. 使用栈存储数字
    • 遍历表达式中的每个元素,遇到数字则入栈。
    • 遇到运算符时,弹出栈顶的两个数字进行计算,将结果入栈。
  2. 逆序操作
    • 因为 num2 - num1num2 / num1 的顺序要求,我们需注意先弹出的数字为右操作数,第二个弹出的是左操作数。
  3. 最终结果
    • 扫描完表达式后,栈中只剩一个元素,即为计算结果。

反思

  1. 栈的使用:栈的后进先出特性很适合逆波兰表达式的求值。每次遇到运算符时取出两个操作数,可以实现正确的运算顺序。
  2. 操作符的判断:在Java中需要使用 .equals() 来判断字符串是否相等。需要特别注意 "/""-" 的运算顺序。
  3. 边界处理:因为题目保证表达式有效,因此不用处理异常情况,如除零、非法字符等。

代码

java">class Solution {public int evalRPN(String[] tokens) {Deque<Integer> nums = new ArrayDeque<>();for(int i=0;i<tokens.length;i++){if (tokens[i].equals("+")) {int num1=nums.pop();int num2=nums.pop();nums.push(num1+num2);} else if (tokens[i].equals("-")) {int num1=nums.pop();int num2=nums.pop();nums.push(num2-num1);} else if (tokens[i].equals("*")) {int num1=nums.pop();int num2=nums.pop();nums.push(num2*num1);}else if (tokens[i].equals("/")) {int num1=nums.pop();int num2=nums.pop();nums.push(num2/num1);}else {nums.push(Integer.parseInt(tokens[i]));}}return nums.pop();}
}

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

给定一个整数数组 nums 和一个大小为 k 的滑动窗口,该窗口从数组的最左侧移动到最右侧。每次只能看到滑动窗口内的 k 个数字,并且滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。


解题思路

可以使用双端队列 deque 来实现滑动窗口最大值的计算。deque 维护当前滑动窗口的最大元素的索引,保证队列的第一个元素为当前窗口的最大值的索引:

  1. 维护双端队列:对于每个新元素,检查队列的有效性,移除不在窗口范围内的元素(索引小于当前窗口的左边界)。
  2. 移除较小元素:对于即将加入窗口的元素,移除队列尾部比当前元素小的所有元素,确保队列从前到后保持一个递减的顺序。
  3. 窗口最大值:每次当索引超过窗口大小时,将队列头部的元素索引对应的值作为窗口的最大值记录到结果数组中。

反思

  1. 双端队列的优势:利用双端队列,可以在 O(n) 的时间复杂度内完成滑动窗口最大值的求解。每个元素最多进出队列一次,效率极高。
  2. 边界检查:在 poll 方法中,用 if 语句代替 while,可以减少不必要的重复检查并提高代码可读性。
  3. 优化添加和移除操作:在每次移除和添加元素时,利用 deque 的头部和尾部操作保证队列内容和窗口范围的一致性。

代码

java">class MyQueue{Deque<Integer> deque = new LinkedList<>();void poll(int val){if(!deque.isEmpty() && val==deque.peek()){deque.poll();}}void add(int val){while(!deque.isEmpty() && val>deque.getLast()){deque.removeLast();}deque.add(val);}int peek(){return deque.peek();}
}
class Solution {public int[] maxSlidingWindow(int[] nums, int k) {if(nums.length == 1){return nums;}int len = nums.length-k+1;int[] res = new int[len];MyQueue myQueue = new MyQueue();int num = 0;for(int i=0;i<k;i++){myQueue.add(nums[i]);}res[num++] = myQueue.peek();for(int i=k;i<nums.length;i++){myQueue.poll(nums[i-k]);myQueue.add(nums[i]);res[num++] = myQueue.peek();}return res;}
}
java">class Solution {public int[] maxSlidingWindow(int[] nums, int k) {ArrayDeque<Integer> deque = new ArrayDeque<>();int n = nums.length;int[] res = new int[n - k + 1];int idx=0;for(int i=0;i<nums.length;i++){while(!deque.isEmpty() && deque.peek() < i-k+1){deque.poll();}while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]){deque.pollLast();}deque.offer(i);if(i>=k-1){res[idx++] =  nums[deque.peek()];}}return res;}
}

347.前 K 个高频元素

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

给定一个非空的整数数组 nums,返回其中出现频率前 k 高的元素。


解题步骤

  1. 构建频率哈希表:遍历数组 nums,记录每个元素出现的频率,使用 HashMap 存储元素及其对应的频率。
  2. 维护大小为 k 的优先队列:利用优先队列(堆)保存频率最高的前 k 个元素。
    • 大顶堆:直接将所有元素放入堆中,然后弹出前 k 个元素。
    • 小顶堆:逐步添加元素至堆中,超过 k 个时删除堆顶最小元素。堆中最后剩下的 k 个元素即为频率前 k 高的元素。
  3. 结果输出:将优先队列中的元素依次出队,存入结果数组。

反思

  1. 优先队列(堆)应用:使用小顶堆在存储容量为 k 的情况下实现频率筛选,从而减少时间复杂度。
  2. 空间优化:在大数据量下,利用 PriorityQueue 实现频率最高的前 k 个元素筛选,有效避免对整个数据集排序。
  3. 边界条件:注意当 k 大于 nums 中不同元素个数时,可能出现特殊情况。

java">class Solution {public int[] topKFrequent(int[] nums, int k) {Map<Integer,Integer> map = new HashMap<>();for(int num:nums){map.put(num,map.getOrDefault(num,0)+1);}PriorityQueue<int[]> pq = new PriorityQueue<>((pair1,pair2) -> pair2[1] - pair1[1]);for(Map.Entry<Integer,Integer> entry : map.entrySet()){pq.add(new int[]{entry.getKey(),entry.getValue()});}int[] ans = new int[k];for(int i =0;i<k;i++){ans[i] = pq.poll()[0];}return ans;}
}
java">class Solution {public int[] topKFrequent(int[] nums, int k) {// 优先级队列,为了避免复杂 api 操作,pq 存储数组// lambda 表达式设置优先级队列从大到小存储 o1 - o2 为从小到大,o2 - o1 反之PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);int[] res = new int[k]; // 答案数组为 k 个元素Map<Integer, Integer> map = new HashMap<>(); // 记录元素出现次数for (int num : nums) map.put(num, map.getOrDefault(num, 0) + 1);for (var x : map.entrySet()) { // entrySet 获取 k-v Set 集合// 将 kv 转化成数组int[] tmp = new int[2];tmp[0] = x.getKey();tmp[1] = x.getValue();pq.offer(tmp);// 下面的代码是根据小根堆实现的,我只保留优先队列的最后的k个,只要超出了k我就将最小的弹出,剩余的k个就是答案if(pq.size() > k) {pq.poll();}}for (int i = 0; i < k; i++) {res[i] = pq.poll()[0]; // 获取优先队列里的元素}return res;}
}

http://www.ppmy.cn/news/1542324.html

相关文章

安装redis教程(Windows,Linux)

Redis介绍 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、基于内存的键值存储数据库。它通常用于需要快速访问的数据场合&#xff0c;如作为缓存系统、消息队列、短暂数据存储等。以下是 Redis 的一些主要特点&#xff1a; 1. 数据结构丰富&#xff1…

BiRefNet:颠覆图像分割,AI黑科技再升级

BiRefNet&#xff1a;颠覆图像分割&#xff0c;AI黑科技再升级 BiRefNet 是一款超强的图像分割 AI 模型&#xff0c;精准度惊人✨&#xff0c;适用于医疗、农业、工业等多个领域&#x1f30d;&#xff0c;让图像处理变得简单高效&#xff01;快来体验这款黑科技吧&#xff01;…

Node-Red二次开发:git下载本地打镜像docker部署

一、先从https://github.com/node-red/node-red.git把代码拉下来&#xff0c;用vscode打开&#xff1b; 二、然后npm install安装以下&#xff0c;把node_models下载下来&#xff0c;然后使用npm run dev启动&#xff0c;如果http://127.0.0.1:1880可以访问就代表node-red启动成…

iOS AVAudioSession 详解【音乐播放器的配置】

前言 在 iOS 音频开发中&#xff0c;AVAudioSession 是至关重要的工具&#xff0c;它控制着应用的音频行为&#xff0c;包括播放、录音、后台支持和音频中断处理等。对于音乐播放器等音频需求强烈的应用&#xff0c;设计一个合理的 AVAudioSession 管理体系不仅能保证音频播放…

小米电机与STM32——CAN通信

背景介绍&#xff1a;为了利用小米电机&#xff0c;搭建机械臂的关节&#xff0c;需要学习小米电机的使用方法。计划采用STM32驱动小米电机&#xff0c;实现指定运动&#xff0c;为此需要了解他们之间的通信方式&#xff0c;指令写入方法等。花了很多时间学习&#xff0c;但网络…

Docker中如何控制服务启动顺序实现探讨

文章目录 一、Docker概述二、Docker三剑客1. Compose2. Machine3. Swarm 三、简要需求1. 样例工程2. 代码模块3. 调用方向4. 期望启动顺序 四、思路分析1.各走各路1.&#xff09;docker-compose -f指定不同配置文件2.&#xff09;docker-compose up -d service-name指定服务名3…

侯捷 | C++ | 内存管理 | 学习笔记(一): 第一章节 primitives

侯捷 | C | 内存管理 | 学习笔记&#xff08;一&#xff09; 第一章节 primitives 重点&#xff1a;技术的演进 new delete针对一个对象->static alloctor针对一个类->globa allocator针对一个标准库&#xff0c;里面有16个链表&#xff08;static alloctor只有一个链…

开源数据库 - mysql - 组织结构(与oracle的区别)

组织形式区别 mysql&#xff08;Schema -> Table -> Column -> Row&#xff09; Schema&#xff08;方案&#xff09;&#xff1a; Scheme是关于数据库和表的布局及特性的信息。它可以用来描述数据库中特定的表以及整个数据库和其中表的信息&#xff0c;如表的一些特…