2021.4.27-2021.5.5
五一假期中间有几天节奏乱掉了 惭愧惭愧
涉及题目为 线程池和任务队列相关问题&字节校园每日一题—— 主要是对队列进行操作相关的题目(恕我段位太低 并没有体会到线程池)
第三周刷题结束后 进行一个简单总结
本周额外找来了一些字节校园的每日一题(刷着有收获的)
本总结包含——
【1】每道题的代码设计思路
照着代码设计思路来套代码 香~
【2】C++/Java实现的代码
由于本人太笨 所以代码的注释做得贼足(注释如有问题 感恩大佬的指正~)
希望能让像我一样的小白们也能看懂代码以及思路hhh
【3】每道题的力扣链接
只看不敲怎么起到练习作用!
赶紧打开链接把代码敲一遍!!
一次搞不懂就清空了敲两次!
冲冲冲!
题目参考开课吧某算法课程胡船长给出的内容~
题号 | 链表的复习 |
---|---|
LC86 | 分隔链表 |
LC138 | 复制带随机指针的链表 |
题号 | 队列的封装与使用 |
---|---|
LC622 | 设计循环队列 |
LC641 | 设计循环双端队列 |
LC1670 | 设计前中后队列 |
LC933 | 最近的请求次数 |
题号 | 字节校园每日一题 |
---|---|
LC103 | 二叉树的锯齿形层序遍历 |
LC350 | 两个数组的交集II |
LC1283 | 使结果不超过阈值的最小除数 |
文章目录
LC86 分隔链表
1.读题
2.代码逻辑
【1】先定义大链表(装大于等于x的值)和小链表(装小于x的值)
【2】开始遍历head链表
【3】在遍历的过程中 根据当前节点的值与x的关系 进行大/小链表的插入
【4】最后将大小链表拼在一起就行啦~
3.Java代码
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode smallHead = new ListNode(0);
ListNode bigHead = new ListNode(0);
ListNode smallTail = smallHead;
ListNode bigTail = bigHead;
//遍历head链表
while(head != null) {
//若当前节点的值小于x 则把当前节点挂到小链表的后面
if(head.val < x) {
smallTail = smallTail.next = head;
}
else {
bigTail = bigTail.next = head;
}
head = head.next;
}
smallTail.next = bigHead.next;
bigTail.next = null;
return smallHead.next;
}
}
LC138 复制带随机指针的链表
1.读题
原题巨长 稍微精简了下题意
给你一个长度为n的链表 每个节点包含一个额外增加的随机指针random
这个指针可以指向链表中的任何节点或空节点
构造这个链表的深拷贝
深拷贝应该正好由n个全新节点组成 其中每个新节点的值都设为其对应的原节点的值。
新节点的next random指针也都应该指向复制链表中的新节点 并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
例如 如果原链表中有X Y两个节点 其中
X.random-->Y
那么在复制链表中对应的两个节点x 和 y 同样有x.random--y>
返回复制链表的头节点
用一个由n个节点组成的链表来表示输入/输出中的链表 每个节点用一个[val, random_index]
表示
val
一个表示 Node.val的整数random_index
随机指针指向的节点索引(范围从0到n-1)如果不指向任何节点 则为null
我们的代码只接受原链表的头节点head
作为传入参数
本题参考题解
3.Java代码
class Solution {
public Node copyRandomList(Node head) {
if(head == null) {
return null;
}
//创建一个哈希表map key是原节点 value是新节点
Map<Node, Node> map = new HashMap<Node, Node>(); //利用java.util中的集合类Map
Node p = head;
//将原节点和新节点放入哈希表中
while(p != null) {
Node newNode = new Node(p.val);
map.put(p,newNode);//将原节点p和新节点newNode全添加到哈希表中~
p = p.next;//p从头节点开始 一直到 遍历完集合中的最后一个元素
}
p = head;
//遍历原链表 设置新节点的next 和 random
while(p != null) {
Node newNode = map.get(p);
//p是原节点 map.get(p)是对应的新节点
//map.get(p.next)是原节点下一个对应的新节点
if (p.next != null) {
newNode.next = map.get(p.next);
}
//p.random是原节点随机指向
//map.get(p.random)是原节点随机指向对应的新节点
if(p.random != null) {
newNode.random = map.get(p.random);
}
p = p.next;
}
//返回头节点
return map.get(head);
}
}
LC622 设计循环队列
队列的题来啦!
主要就是考察一个封装的思维~
我的力扣题解(第一次写题解QAQ)
我的刷题笔记
设计循环队列
1.读题
设计你的循环队列(也被称为“环形缓冲器”)实现。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
本题我们要实现支持如下操作的方法
MyCircularQueue(k)
: 构造器,设置队列长度为 k 。Front
: 从队首获取元素。如果队列为空,返回 -1 。Rear
: 获取队尾元素。如果队列为空,返回 -1 。enQueue(value)
: 向循环队列插入一个元素。如果成功插入则返回真。deQueue()
: 从循环队列中删除一个元素。如果成功删除则返回真。isEmpty()
: 检查循环队列是否为空。isFull()
: 检查循环队列是否已满。
2.代码逻辑
这题没啥逻辑好说了
1.先写构造器
【1】队列容量
【2】头指针
【3】尾指针
【4】当前队列中的元素个数
2.之后进行队列的初始化(定好是多长的队列)
3.之后写好入队 出队的方法就行 别忘了return false 和 true
4.获取队头&尾的元素 更简单辽
5.判空 判满 这。。就一个if就完事了哦
3.Java代码
这个代码妙在 使用计数器对队列中元素个数进行了一个记录 省去了一些步骤~
class MyCircularQueue {
int[] arr;//定义队列数组
int size;//定义好队列的总容量!
int head;//头指针
int tail;//尾指针
int count;//计数器 用来记录现在队列中有多少元素
public MyCircularQueue(int k) {
//写好构造器ÿ