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

news2024/11/25 6:35:28

文章目录

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

刷题前唠嗑


LeetCode?启动!!!

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

题目:设计前中后队列

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

题目描述

代码与解题思路

type FrontMiddleBackQueue struct {
    queue []int
    size int
}

func Constructor() FrontMiddleBackQueue {
    return FrontMiddleBackQueue {
        queue: make([]int, 1001), 
        size: 0,
    }
}

func (this *FrontMiddleBackQueue) PushFront(val int)  {
    tmp := make([]int, 1001)
    tmp[0] = val
    for i := 1; i < this.size+1; i++ {
        tmp[i] = this.queue[i-1]
    }
    this.queue = tmp
    this.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] = val
    for i := this.size/2+1; i < this.size+1; i++ {
        tmp[i] = this.queue[i-1]
    }
    this.queue = tmp
    this.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] = val
    this.queue = tmp
    this.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.List
    right *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  *Deque
    right *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  []int
    right []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
}

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

结语

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebUI自动化学习(Selenium+Python+Pytest框架)003

1.元素操作 在成功定位到元素之后&#xff0c;我们需要对元素进行一些操作动作。常用的元素操作动作有&#xff1a; &#xff08;1&#xff09;send_keys() 键盘动作&#xff1a;向浏览器发送一个内容&#xff0c;通常用于输入框输入内容或向浏览器发送快捷键 &#xff08;2…

C语言——有一个3*4的矩阵,要求求出其中值最大的那个元素的值,以及其所在的行号和列号

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int i,j,row0,colum0,a[3][4]{{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};int maxa[0][0];for ( i 0; i < 3; i)//行&#xff08;row&#xff09;{for ( j 0; j < 4; j)//列&#xff08;colum&#xf…

【FGPA】Verilog:JK 触发器 | D 触发器 | T 触发器 | D 触发器的实现

0x00 JK 触发器 JK 触发器是 RS 触发器和 T 触发器的组合&#xff0c;有两个输入端 J 和 K&#xff0c;如果两个输入端都等于 1&#xff0c;则将当前值反转。 行为表 状态图 Timing Diagram Circuit JK 触发器的设计目的是防止 RS 触发器在输入 S 和 R 均等于 …

Unity学习笔记11

一、视频播放功能 1.如何让视频在游戏场景中播放&#xff1f; 在Assets目录下添加一个渲染器纹理&#xff0c;步骤&#xff1a;新建→渲染器纹理 首先在创建一个平面&#xff0c;想让视频在平面上显示。在平面上添加一个组件 Video Player 然后将视频文件拖拽到视频剪辑位置上…

sed应用

一.sed 1.Sed概述 sed编辑器时一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据&#xff0c;这些命令要么从命令行中输入&#xff0c;要存储在一个命令文本文件中。 2.sed命令的格…

网络安全--基于Kali的网络扫描基础技术

文章目录 1. 标准ICMP扫描1.1使用Ping命令1.1.1格式1.1.2实战 1.2使用Nmap工具1.2.1格式1.2.2实战1.2.2.1主机在线1.2.2.2主机不在线 1.3使用Fping命令1.3.1格式1.3.2实战 2. 时间戳查询扫描2.1格式2.2实战 3. 地址掩码查询扫描3.1格式3.2实战 2. TCP扫描2.1TCP工作机制2.2TCP …

IDEA编译器的永久试用设置与基本使用

参考视频&#xff1a; 最通俗易懂的JDK、IDEA的安装使用权威指南 2023新版前端Web开发HTML5CSS3移动web视频教程&#xff0c;前端web入门首选黑马程序员 文章目录 一.安装包下载与安装二.设置IDEA永久试用三.IDEA的基本试用0.IDEA管理Java程序的结构1.工程创建2.模块创建3.包创…

【Java】使用 IDEA 快速生成 SpringBoot 模块

项目目录下新建 module 模块 在 pom.xml 更改为 spring initializr 配置之后的 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchem…

yolov8-seg 分割推理流程

目录 一、分割检测 二、图像预处理 二、推理 三、后处理与可视化 3.1、后处理 3.2、mask可视化 四、完整pytorch代码 一、分割检测 注&#xff1a;本篇只是阐述推理流程&#xff0c;tensorrt实现后续跟进。 yolov8-pose的tensorrt部署代码稍后更新&#xff0c;还是在仓…

如何根据接口文档,轻松快速的模拟接口服务?

什么是WireMock? WireMock 是一个Http 模拟服务,其核心也是一个web服务,WireMock主要是为特定请求提供固定的返回值。 WireMock可以作为单独进程启动,模拟一个WEB服务器,提供一些API访问,并返回特定的返回值。也可以作为第三方库在项目中使用。 如何使用 standalone方…

csdn博客编写技巧

随便记录一下csdn博客编写时候用的到技巧&#xff0c;以作备忘。 1. 表格 1.1 Markdown-Table-Generator 这个是csdn编辑器中&#xff0c;工具栏自带的表格用法。主要优点是比较直观&#xff0c;缺点是无法设置表格中行列的宽高。 用法&#xff1a; | 表头一 | 表头二 | |-…

贪心算法(新坑)

贪心入门 概述&#xff1a; 贪心算法是一种在每一步选择中都采取当前最优解的策略&#xff0c;希望最终能够得到全局最优解的算法。简单来说&#xff0c;它会不断地做出局部最优的选择&#xff0c;相信通过这种选择最终能够达到全局最优。 举个例子来说明。假设你要从一个迷…

Vue基本使用(一)

&#x1f4d1;前言 本文主要是【Vue】——Vue基本使用的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&#x…

【CAD二次开发】标注箭头,获取修改标注箭头图块

常见的的标注箭头有以下种类 public static List<string> ArrowBlock = new List<string>(){" ","_CLOSEDBLANK&

淘宝API接口系列:连接商户与消费者的桥梁

一、引言 淘宝&#xff0c;作为中国最大的电商平台之一&#xff0c;拥有数以亿计的注册用户和海量的商品信息。淘宝API接口作为连接商户与消费者的重要桥梁&#xff0c;为开发者提供了丰富的电商资源&#xff0c;帮助他们创新和优化业务。本文将深入探讨淘宝API接口的相关知识…

软件设计开发规程文件

《软件设计开发规程文件》 目的&#xff1a;为需求设计、开发、实现解决方案。

LLM大语言模型

大语言模型的定义 大语言模型&#xff08;英文&#xff1a;Large Language Model&#xff0c;缩写LLM&#xff09;&#xff0c;也称大型语言模型&#xff0c;是一种人工智能模型&#xff0c;旨在理解和生成人类语言。它们在大量的文本数据上进行训练&#xff0c;可以执行广泛的…

怎么更新BI报表数据?问我就对了

BI大数据分析工具上有大量的BI报表模板&#xff0c;这些模板都是一个个完整的BI报表&#xff0c;只需将数据源更换&#xff0c;立即就能用来分析我们自己的数据。那&#xff0c;BI报表的数据怎么更新&#xff1f;接下来就来说说这事。 目的&#xff1a;更新BI报表数据 工具&a…

PPSSPP (PSP游戏模拟器)最新版安装使用教程

PPSSPP优势 1、目前唯一的也是最好的psp模拟器 可运行绝大多数psp游戏且运行高速&#xff0c;即使是低配手机也能游玩经典大作。 2、支持自定义调节虚拟手柄和实体手柄连接 ppsspp模拟器支持使用虚拟手柄或者连接实体手柄游玩&#xff0c;同时还可以自定义调节按键选项。 …

微信小程序+中草药分类+爬虫+keras

目录 1 介绍2 数据爬虫3 模型训练和验证3.1 模型训练3.2 导入一张图片进行验证 4 后台flask部署5 微信小程序 1 介绍 本项目使用深度学习模型&#xff0c;训练5种中药材数据集&#xff0c;然后将其集成到微信小程序&#xff0c;通过微信小程序拍照&#xff0c;将图片传输给后端…