【LeetCode】每日一题 2023_11_28 设计前中后队列(数组/链表/双端队列)

2023-11-29 16:44

本文主要是介绍【LeetCode】每日一题 2023_11_28 设计前中后队列(数组/链表/双端队列),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 刷题前唠嗑
  • 题目:设计前中后队列
    • 题目描述
    • 代码与解题思路
    • 偷看大佬题解
  • 结语

刷题前唠嗑


LeetCode?启动!!!

这道题的难度,才是我想象中的中等题的难度好吧,昨天那玩意对我来说还是太难了。。。

题目:设计前中后队列

题目链接:1670. 设计前中后队列

题目描述

代码与解题思路

type FrontMiddleBackQueue struct {queue []intsize int
}func Constructor() FrontMiddleBackQueue {return FrontMiddleBackQueue {queue: make([]int, 1001), size: 0,}
}func (this *FrontMiddleBackQueue) PushFront(val int)  {tmp := make([]int, 1001)tmp[0] = valfor i := 1; i < this.size+1; i++ {tmp[i] = this.queue[i-1]}this.queue = tmpthis.size++
}func (this *FrontMiddleBackQueue) PushMiddle(val int)  {tmp := make([]int, 1001)for i := 0; i < this.size/2; i++ {tmp[i] = this.queue[i]}tmp[this.size/2] = valfor i := this.size/2+1; i < this.size+1; i++ {tmp[i] = this.queue[i-1]}this.queue = tmpthis.size++
}func (this *FrontMiddleBackQueue) PushBack(val int)  {tmp := make([]int, 1001)for i := 0; i < this.size; i++ {tmp[i] = this.queue[i]}tmp[this.size] = valthis.queue = tmpthis.size++
}func (this *FrontMiddleBackQueue) PopFront() int {if this.size == 0 {return -1}ans := this.queue[0]this.queue = this.queue[1:]this.size--return ans
}func (this *FrontMiddleBackQueue) PopMiddle() int {if this.size == 0 {return -1}ans := this.queue[(this.size-1)/2]this.queue = append(this.queue[:(this.size-1)/2], this.queue[(this.size-1)/2+1:]...)this.size--return ans
}func (this *FrontMiddleBackQueue) PopBack() int {if this.size == 0 {return -1}ans := this.queue[this.size-1]this.queue = this.queue[:this.size-1]this.size--return ans
}

快来欣赏一下我的数组屎山,当时一开始做的时候我在想是用链表做还是数组做,链表做肯定是更优的,但是我感觉链表可能比较麻烦(事实证明数组更麻烦。。。早知道用链表写了,后悔)

题目的思路就是:跟着题目要求写就行了,主要考察的是代码能力

偷看大佬题解

Go 链表实现:

// 第一种写法:链表
type FrontMiddleBackQueue struct {left  *list.Listright *list.List
}func Constructor() FrontMiddleBackQueue {return FrontMiddleBackQueue{left:  list.New(),right: list.New(),}
}// 调整长度,保证 0 <= right.Len() - left.Len() <= 1
// 从而保证可以在正中间插入删除元素
func (q *FrontMiddleBackQueue) balance() {if q.left.Len() > q.right.Len() {q.right.PushFront(q.left.Remove(q.left.Back()))} else if q.right.Len() > q.left.Len()+1 {q.left.PushBack(q.right.Remove(q.right.Front()))}
}func (q *FrontMiddleBackQueue) PushFront(val int) {q.left.PushFront(val)q.balance()
}func (q *FrontMiddleBackQueue) PushMiddle(val int) {if q.left.Len() < q.right.Len() {q.left.PushBack(val)} else {q.right.PushFront(val)}
}func (q *FrontMiddleBackQueue) PushBack(val int) {q.right.PushBack(val)q.balance()
}func (q *FrontMiddleBackQueue) PopFront() (val int) {if q.right.Len() == 0 { // 整个队列为空return -1}if q.left.Len() > 0 {val = q.left.Remove(q.left.Front()).(int)} else {val = q.right.Remove(q.right.Front()).(int)}q.balance()return
}func (q *FrontMiddleBackQueue) PopMiddle() int {if q.right.Len() == 0 { // 整个队列为空return -1}if q.left.Len() == q.right.Len() {return q.left.Remove(q.left.Back()).(int)}return q.right.Remove(q.right.Front()).(int)
}func (q *FrontMiddleBackQueue) PopBack() int {if q.right.Len() == 0 { // 整个队列为空return -1}val := q.right.Remove(q.right.Back()).(int)q.balance()return val
}

Go 双端队列实现

// 第二种写法:四个 slice
type FrontMiddleBackQueue struct {left  *Dequeright *Deque
}func Constructor() FrontMiddleBackQueue {return FrontMiddleBackQueue{left:  &Deque{},right: &Deque{},}
}// 调整长度,保证 0 <= right.Len() - left.Len() <= 1
// 从而保证可以在正中间插入删除元素
func (q *FrontMiddleBackQueue) balance() {if q.left.Len() > q.right.Len() {q.right.PushFront(q.left.PopBack())} else if q.right.Len() > q.left.Len()+1 {q.left.PushBack(q.right.PopFront())}
}func (q *FrontMiddleBackQueue) PushFront(val int) {q.left.PushFront(val)q.balance()
}func (q *FrontMiddleBackQueue) PushMiddle(val int) {if q.left.Len() < q.right.Len() {q.left.PushBack(val)} else {q.right.PushFront(val)}
}func (q *FrontMiddleBackQueue) PushBack(val int) {q.right.PushBack(val)q.balance()
}func (q *FrontMiddleBackQueue) PopFront() (val int) {if q.right.Len() == 0 { // 整个队列为空return -1}if q.left.Len() > 0 {val = q.left.PopFront()} else {val = q.right.PopFront()}q.balance()return
}func (q *FrontMiddleBackQueue) PopMiddle() int {if q.right.Len() == 0 { // 整个队列为空return -1}if q.left.Len() == q.right.Len() {return q.left.PopBack()}return q.right.PopFront()
}func (q *FrontMiddleBackQueue) PopBack() int {if q.right.Len() == 0 { // 整个队列为空return -1}val := q.right.PopBack()q.balance()return val
}// 两个 slice 头对头,即可实现双端队列
// 但这并不是一个「工业级」的实现,因为 slice 没有「缩容」的概念
// 这意味着在大量的 pop 操作后,会产生大量无法被自动 GC 的空间
type Deque struct {left  []intright []int
}func (q Deque) Empty() bool {return len(q.left) == 0 && len(q.right) == 0
}func (q Deque) Len() int {return len(q.left) + len(q.right)
}func (q *Deque) PushFront(v int) {q.left = append(q.left, v)
}func (q *Deque) PushBack(v int) {q.right = append(q.right, v)
}func (q *Deque) PopFront() (v int) {if len(q.left) > 0 {q.left, v = q.left[:len(q.left)-1], q.left[len(q.left)-1]} else {v, q.right = q.right[0], q.right[1:]}return
}func (q *Deque) PopBack() (v int) {if len(q.right) > 0 {q.right, v = q.right[:len(q.right)-1], q.right[len(q.right)-1]} else {v, q.left = q.left[0], q.left[1:]}return
}

用官方题解评论区大佬的话来说就是,双端队列考思路,链表解法考代码能力。这就是这道题考察的点。

结语

终于,又做出了一道每日一题,晕倒了

这篇关于【LeetCode】每日一题 2023_11_28 设计前中后队列(数组/链表/双端队列)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

Java 队列Queue从原理到实战指南

《Java队列Queue从原理到实战指南》本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效... 目录一、队列的认识队列的底层与集合框架常见的队列方法插入元素方法对比(add和offer)移除元素方法

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

RabbitMQ 延时队列插件安装与使用示例详解(基于 Delayed Message Plugin)

《RabbitMQ延时队列插件安装与使用示例详解(基于DelayedMessagePlugin)》本文详解RabbitMQ通过安装rabbitmq_delayed_message_exchan... 目录 一、什么是 RabbitMQ 延时队列? 二、安装前准备✅ RabbitMQ 环境要求 三、安装延时队

Java集合中的链表与结构详解

《Java集合中的链表与结构详解》链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序的通过链表中的引用链接次序实现,文章对比ArrayList与LinkedList的结构差异,详细讲解了链表... 目录一、链表概念与结构二、当向单链表的实现2.1 准备工作2.2 初始化链表2.3 打印数据、链表长

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一