【每日一题】设计前中后队列

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:双指针
  • 写在最后

Tag

【设计类】【队列】【数组】【2023-11-28】


题目来源

1670. 设计前中后队列


题目解读

设计一个队列,可以实在在前、中、后三个位置的 push 和 pop 操作。


解题思路

维护一个数组,在数组中使用指针指向前、后两个位置并维护两个的指向。本题还可以使用 vector 容器,可以省去移动的操作,这里没有介绍该方法,读者可以自行实现。

方法一:双指针

初始化

FrontMiddleBackQueue() {front = CENTER;rear = front - 1;
}

使用两个指针 frontrear 分别指向数组 data 的 “前后” 两个位置。初始化 data 数组,int data[5000],接着初始化 front = 2500rear = front - 1

getCount

int getCont(){return rear - front + 1;
}

push 和 pop 操作

前、后两个位置的 pushpop 操作很容易实现:

void pushFront(int val) {data[--front] = val;
}void pushBack(int val) {data[++rear] = val;
}

pushFront 之前先对 front 指针 --,然后将 val 插入到该位置。在 pushBack 中需要先 ++ rear,然后插入 val


int popFront() {if(getCont() == 0){return -1;}int val = data[front++];    // 弹出Front之后front变为前插下个数的后一个位置return val;
}int popBack() {if(getCont() == 0){return -1;}int val = data[rear--];     // 弹出Back之后rear变为尾插下个数的前一个位置return val;
}

pop 操作之前需要先判断 data 是否为空,如是则返回 -1;否则弹出对应的元素并更改指针为 “下一个” 元素。

pushMiddle

记此时数组 data 的长度为 cnt,我们需要根据 cnt 的不同对 pushMiddle 进行分情况讨论:

  • cnt = 1 时,此时的 middle 位置为 font - 1,记为 pushPos = font - 1
  • 否则,pushPos = font + (cnt / 2)

接着需要将 val 插入到 pushPos 位置,如果 cnt = 1,可以直接 pushFront(val);否则不能直接在 pushPos 插入 val,需要先将 pushPos 及之后的元素依次向后移动一位,将 pushPos 位置空出,然后将 val 插入到 pushPos 位置,或者将pushPos 及之前的元素依次向前移动一位,将 pushPos 位置空出,然后将 val 插入到 pushPos 位置。

以下是后移的示例代码:

void pushMiddle(int val) {int cnt = getCont();if(cnt == 1){pushFront(val);return;}int pushPos = front+(cnt/2);for(int i = rear+1; i > pushPos; --i){data[i] = data[i-1];}data[pushPos] = val;++rear;
}

popMiddle

pop 之前需要先判断数组是否为空,如是直接返回 -1,否则需要先找到 popPos 即需要弹出的位置,由数学归纳知 popPos = front + (n - 1) / 2n 为数组此时的长度。

弹出 popPos 位置的元素之后,需要将 popPos 之后的元素依次左移一位填充空格,然后 --rear。示例代码如下:

int popMiddle() {int cnt = getCont();if(cnt == 0){return -1;}int popPos = front + (cnt - 1)/2;int tmp = data[popPos];for(int i = popPos; i < rear; ++i){data[i] = data[i+1];}--rear;return tmp;
}

实现代码

class FrontMiddleBackQueue {#define CENTER 2500int data[5000];int front, rear;
public:FrontMiddleBackQueue() {front = CENTER;rear = front - 1;}int getCont(){return rear - front + 1;}void pushFront(int val) {data[--front] = val;}/*个数  插入位置X     front-1     特殊情况XX    front+1XXX   front+1XXXX  front+2...   ...n个数 front+(n/2)
*/		void pushMiddle(int val) {int cnt = getCont();if(cnt == 1){pushFront(val);return;}int pushPos = front+(cnt/2);for(int i = rear+1; i > pushPos; --i){data[i] = data[i-1];}data[pushPos] = val;++rear;}void pushBack(int val) {data[++rear] = val;}int popFront() {if(getCont() == 0){return -1;}int val = data[front++];    // 弹出Front之后front变为前插下个数的后一个位置return val;}/*个数  pop位置X     front    特殊情况XX    frontXXX   front+1XXXX  front+1XXXXX front+2...   ...n个数 front+(n-1/2)
*/int popMiddle() {int cnt = getCont();if(cnt == 0){return -1;}int popPos = front + (cnt - 1)/2;int tmp = data[popPos];for(int i = popPos; i < rear; ++i){data[i] = data[i+1];}--rear;return tmp;}int popBack() {if(getCont() == 0){return -1;}int val = data[rear--];     // 弹出Back之后rear变为尾插下个数的前一个位置return val;}
};

复杂度分析

时间复杂度:pushFrontpushBackpopFront 以及 popBack 一次操作的时间复杂度均为 O ( 1 ) O(1) O(1)pushMiddlepopMiddle n 次操作的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( n ) O(n) O(n)


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

建筑红模板尺寸规格

红模板是建筑施工中常用的一种模板材料&#xff0c;具有较好的承重能力和稳定性。在建筑工程中&#xff0c;正确选择合适的红模板尺寸规格对于施工质量和效率至关重要。本文将介绍一些关于红模板尺寸规格的信息&#xff0c;帮助您更好地了解和选择适合的红模板。 以下是关于红模…

Apache2.4 AliasMatch导致301重定向问题?

环境&#xff1a;ubuntu18.04-desktop apache2版本&#xff1a; rootubuntu:/etc/apache2# apache2ctl -v Server version: Apache/2.4.29 (Ubuntu) Server built: 2023-03-08T17:34:33apache配置&#xff1a; DocumentRoot /var/www/html # Alias就没事 # Alias "/my…

Docker | 自定义Docker镜像

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;Docker系列 ✨特色专栏&#xff1a; My…

Leetcode刷题之设计循环队列(C语言版)

Leetcode刷题之设计循环队列&#xff08;C语言版&#xff09; 一、题目描述二、题目示例三、题目解析Ⅰ、typedef structⅡ、MyCircularQueue* myCircularQueueCreate(int k)Ⅲ、bool myCircularQueueIsEmpty(MyCircularQueue* obj)Ⅳ、bool myCircularQueueIsFull(MyCircularQ…

Vue3-admin-template 导入模板功能

先看效果&#xff1a; 直接上代码&#xff1a; 1.绑定事件&#xff1a; <el-button type"primary" click"templates">模板导入</el-button> 2.写结构样式 <!-- 模板导入 --><el-dialog v-model"Statusimprot" title&quo…

2023年通过已经认证的微信公众号注册微信小程序

登录已经认证的微信公众号 注册完成后&#xff0c;打开微信公众平台的网址&#xff0c;用账号密码的方式登录

与 PCIe 相比,CXL为何低延迟高带宽?

文章目录 前言1. LatencyPCIE 生产者消费则模型结论Flit 包PCIE/CXL.ioCXL.cace & .mem总结 2. BandWidth常见开销CXL.IO Link efficiencyPCIe Link efficiencyCXL.IO bandwidthCXL.mem/.cache bandwidth 参考 前言 CXL 规范里没有具体描述与PCIe 相比低延时高带宽的原因&…

视频文案怎么写,媒介盒子支招

近几年短视频成为风口&#xff0c;各行各业都想分一杯羹&#xff0c;但是一头热的你&#xff0c;是否知道短视频的相关文案怎么写呢?正所谓兵马未动&#xff0c;文案先行&#xff0c;一个合适的文案是上热门的秘密武器&#xff0c;今天媒介盒子就来和大家聊聊&#xff1a;视频…

【技术干货】宇视IPC音频问题解决步骤

近期技术人员从宇视官网下载sdk进行二次开发时&#xff0c;在启动实时直播&#xff0c;并通过回调函数拿到流数据&#xff0c;发现没有音频流数据。 通过下面的数据发现&#xff0c;codeType此字段一直是28&#xff0c;代表的是H.264数据&#xff0c;但未没发现有音频的数据包…

51单片机项目(16)——基于51单片机的水箱冷却系统

1.项目背景 汽车水箱又称散热器&#xff0c;是汽车冷却系统中主要机件&#xff1b;其功用是散发热量&#xff0c;冷却水在水套中吸收热量&#xff0c;流到散热器后将热量散去&#xff0c;再回到水套内而循环不断。从而达到散热调温的效果。它还是汽车发动机的重要组成部分。 汽…

docker 安装elasticsearch集群

准备工作 docker 安装好&#xff0c;docker compose 安装好编辑好docker-compose.yml文件&#xff08;本文会提供&#xff09;生成elastic-certificates.p12密钥&#xff0c;与docker-compose文件在同一个目录&#xff08;本文会介绍生成方式&#xff09;准备elasticsearch配置…

虚幻学习笔记5—UI预设体制作

一、前言 本文使用的虚幻引擎5.3.2&#xff0c;在unity中有预设体的概念&#xff0c;可以将一个组合型的物体或UI制作成预设体&#xff0c;方便后续可以快速制作更多元的内容和复用。虚幻本身没有这个概念&#xff0c;但是要实现类似的效果其&#xff0c;故此我引用了这个概念。…