双非本科准备秋招(13.1)—— 力扣 栈、队列与堆

2024-02-02 04:12

本文主要是介绍双非本科准备秋招(13.1)—— 力扣 栈、队列与堆,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、103. 二叉树的锯齿形层序遍历

昨天做的二叉树的层序遍历,把代码直接拿过来。

这个题要求的是一个Z型遍历,如下图。

        用一个变量f记录正反顺序,然后使用LinkedList记录答案,下图可以看到LinkedList继承了Deque,所以可以当作双端队列来用。

每次记录答案时,根据f的值选择调用offerLast和offerFirst方法。

class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {LinkedBlockingQueue<TreeNode> q = new LinkedBlockingQueue<>();List<List<Integer>> list = new ArrayList<>();if(root == null) return list;q.offer(root);int cnt = 1;boolean f = true;while(!q.isEmpty()){LinkedList<Integer> L = new LinkedList<>();int temp = 0;for(int i = 0; i < cnt; i++){TreeNode t = q.poll();if(f) L.offerLast(t.val);else L.offerFirst(t.val);if(t.left != null){q.offer(t.left);temp++;}if(t.right != null){q.offer(t.right);temp++;}}cnt = temp;list.add(L);f = !f;}return list;}
}

2、23. 合并 K 个升序链表

        用优先队列来做,默认排序即可(小顶堆),最后处理一下答案,把队列q中的元素转移到新的链表上。

class Solution {public ListNode mergeKLists(ListNode[] lists) {PriorityQueue<Integer> q = new PriorityQueue<>();ListNode head = new ListNode();ListNode p = head;for(int i = 0; i < lists.length; i++){while(lists[i] != null){q.offer(lists[i].val);lists[i] = lists[i].next;}}while(!q.isEmpty()){ListNode t = new ListNode(q.poll());p.next = t;p = p.next;}return head.next;}
}

3、215. 数组中的第K个最大元素

堆这种数据结构就适合求前几个具有xx特性的元素问题,包括下一个题目和最后一个题目。

这个题用小顶堆做,我们可以手写一个堆的结构class MinHeap。

我们只需要把前k个元素加入堆(offer()方法),然后后面的元素只需要判断是否大于堆中的第一个元素即可,如果大于,就替换第一个元素(replace()方法)。

因为堆中第一个元素是k个中最小的,我们不断加入大的元素,那么最后是不是堆中只剩下最大的k个元素了,k个最大元素中最小的不就是堆的第一个元素嘛。

class Solution {public int findKthLargest(int[] nums, int k) {MinHeap heap = new MinHeap(k);for(int i = 0; i < k; i++){heap.offer(nums[i]);}for(int i = k; i < nums.length; i++){if(nums[i] > heap.array[0]){heap.replace(nums[i]);}}return heap.array[0];}
}public class MinHeap {int[] array;int size;public MinHeap(int capacity) {this.array = new int[capacity];}public void offer(int offerd){up(offerd);size++;   }public void up(int offerd){int child = size;while(child > 0){int parent = (child-1)/2;if(array[parent] > offerd){array[child] = array[parent];}else{break;}child = parent;}array[child] = offerd;}public void replace(int replaced){array[0] = replaced;down(0);}private void down(int parent) {int lc = parent*2+1;int rc = lc+1;int min = parent;if(lc < size && array[lc] < array[min]){min = lc;}if(rc < size && array[rc] < array[min]){min = rc;}if(min != parent){swap(min, parent);down(min);}}private void swap(int i, int j) {int t = array[i];array[i] = array[j];array[j] = t;}
}

4、703. 数据流中的第 K 大元素

与上个题不能说一模一样,只能说完全一致。

需要注意add方法要判断一下堆是不是满了,因为初始化堆的时候有可能提供的元素个数小于k个,如果没满直接加入堆就好。

class KthLargest {MinHeap heap = null;public KthLargest(int k, int[] nums) {heap = new MinHeap(k);int len = Math.min(k, nums.length);for(int i = 0; i < len; i++){heap.offer(nums[i]);}for(int i = k; i < nums.length; i++){if(nums[i] > heap.array[0]){heap.replace(nums[i]);}}}public int add(int val) {if(heap.size < heap.array.length){heap.offer(val);}else if(val > heap.array[0]){heap.replace(val);}return heap.array[0];}
}public class MinHeap {int[] array;int size;public MinHeap(int capacity) {this.array = new int[capacity];Arrays.fill(this.array, Integer.MIN_VALUE);}public void offer(int offerd){up(offerd);size++;   }public void up(int offerd){int child = size;while(child > 0){int parent = (child-1)/2;if(array[parent] > offerd){array[child] = array[parent];}else{break;}child = parent;}array[child] = offerd;}public void replace(int replaced){array[0] = replaced;down(0);}private void down(int parent) {int lc = parent*2+1;int rc = lc+1;int min = parent;if(lc < size && array[lc] < array[min]){min = lc;}if(rc < size && array[rc] < array[min]){min = rc;}if(min != parent){swap(min, parent);down(min);}}private void swap(int i, int j) {int t = array[i];array[i] = array[j];array[j] = t;}
}

5、1047. 删除字符串中的所有相邻重复项

解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

读完解释后,感觉就是明示了栈的数据结构。

我们把a入栈,b入栈,b入栈,b和栈顶重复,b不入了并且弹出栈顶元素,这时候栈只剩下a,然后a入栈,a和栈顶重复,a不入了并且弹出栈顶元素,栈空了,然后c入栈,a入栈。

这时候我们依次弹出,得到ac,那么我们可以倒着遍历字符串,倒着入栈,结果都是一样的,不影响删除相邻重复的字母。

class Solution {public String removeDuplicates(String s) {Stack<Character> stack = new Stack<>();for(int i = s.length()-1; i >= 0; i--){if(!stack.isEmpty() && stack.peek() == s.charAt(i)){stack.pop();}else{stack.push(s.charAt(i));}}String ans = "";while(!stack.isEmpty()){ans += stack.pop();}return ans;}
}

6、347. 前 K 个高频元素

        元素与元素的次数,让人联想到哈希表。存到哈希表后,对出现的次数进行排序,这应该是第一思路。

        前k个高频元素,有出现了前几个具有xx特性的这种要求,我们就会想到堆,在堆中只存放前k个高频元素,使用小顶堆,我们最后得到的就是前k个最高频的元素了。

        java中的ProrityQueue的底层就是堆,我就不用自己写的了。因为我们的堆中要存储数据和出现的次数,因此可以存个数组,下标0代表是什么数据,下标1代表出现的次数。        

        我们先加入到map中,然后遍历map集合,把cnt大于堆顶的元素替换掉原来的元素,也就是队列出队,这样就得到了前k个高频的元素了。

class Solution {public int[] topKFrequent(int[] nums, int k) {PriorityQueue<int[]> q = new PriorityQueue<>(k, (o1, o2) -> o1[1] - o2[1]);HashMap<Integer, Integer> map = new HashMap<>();for(int i = 0; i < nums.length; i++){int v = 0;if(map.containsKey(nums[i])){v = map.get(nums[i]);}map.put(nums[i], v+1);}for(Integer n : map.keySet()){int cnt = map.get(n);if(q.size() < k){q.offer(new int[]{n, cnt});}else if(cnt > q.peek()[1]){q.poll();q.offer(new int[]{n, cnt});}}int[] ans = new int[k];int j = 0;while(!q.isEmpty()){ans[j++] = q.poll()[0];}return ans;}
}

这篇关于双非本科准备秋招(13.1)—— 力扣 栈、队列与堆的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/669433

相关文章

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

Redis消息队列实现异步秒杀功能

《Redis消息队列实现异步秒杀功能》在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给Redis处理,并通过异步方式执行,Redis提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Re... 目录1 Redis消息队列1.1 List 结构1.2 Pub/Sub 模式1.3 Stream 结

SpringKafka错误处理(重试机制与死信队列)

《SpringKafka错误处理(重试机制与死信队列)》SpringKafka提供了全面的错误处理机制,通过灵活的重试策略和死信队列处理,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、Spring Kafka错误处理基础二、配置重试机制三、死信队列实现四、特定异常的处理策略五

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

Redis延迟队列的实现示例

《Redis延迟队列的实现示例》Redis延迟队列是一种使用Redis实现的消息队列,本文主要介绍了Redis延迟队列的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、什么是 Redis 延迟队列二、实现原理三、Java 代码示例四、注意事项五、使用 Redi