本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的。同时也希望文章能够让你有所收获,与君共勉!

今天来学习一下用数组模拟链表,又称链式前向星,这里主要介绍单链表与双向链表。

单链表

实现一个单链表,链表初始为空,支持三种操作:

  1. 向链表头插入一个数;
  2. 删除第 k 个插入的数后面的数;
  3. 在第 k 个插入的数后插入一个数。

现在要对该链表进行 M 次操作,进行完所有操作后,从头到尾输出整个链表。

注意:题目中第 k 个插入的数并不是指当前链表的第 k 个数。例如操作过程中一共插入了 n 个数,则按照插入的时间顺序,这 n 个数依次为:第 1 个插入的数,第 2 个插入的数,…第 n 个插入的数。

输入格式

第一行包含整数 M,表示操作次数。

接下来 M 行,每行包含一个操作命令,操作命令可能为以下几种:

H x,表示向链表头插入一个数 x。

D k,表示删除第 k 个插入的数后面的数(当 k 为 0 时,表示删除头结点)。

I k x,表示在第 k 个插入的数后面插入一个数 x(此操作中 k 均大于 0)。

输出格式

共一行,将整个链表从头到尾输出。

数据范围

1≤M≤100000

所有操作保证合法。

输入样例:

10

H 9

I 1 1

D 1

D 0

H 6

I 3 6

I 4 5

I 4 5

I 3 4

D 6

输出样例:

6 4 6 5

算法原理

  1. 定义存储数组以及指针数组,存储数组是存储数字,可视为节点里的数据域,而指针数组是存放存储数组中的某一个元素的下一个位置,可视为结点里面的指针域,最后定义链表头head与指针idx
  2. 初始化头节点head,初始值为-1(遍历链表的终止条件),初始化指针idx,每在idx处插入一个数字就想后一位。
  3. 选择头插法/第k个节点处插入/删除第k个节点(看代码)。

代码实现

需要强调的是,下标从0就开始存储的单向链表,在第k个位置处插入应表示为k-1

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000010;
int e[N],ne[N],idx,head; int main()
{
int n;
cin >> n;
idx = 0;
head = -1; /*1.主要是k的索引,从0开始所以k都要减1,2.再删除的时候要判断是否删除头节点0,如果是就要让head向后一位*/
while(n--){
char c;
int k,x;
cin >> c;
if(c == 'H'){ // 头插
cin >> x;
e[idx] = x;
ne[idx] = head; // 让idx的下一个节点是head
head = idx++; // 再让idx成为head,并且将idx移到下一位
}
else if(c == 'D'){ // 删除第k个插入的数
cin >> k;
if(!k) head = ne[head]; // 如果删除头节点就移动头节点至下一位
else ne[k-1] = ne[ne[k-1]]; // 否则就删除第k位
}
else{
cin >> k >> x;
e[idx] =x;
ne[idx] = ne[k-1]; // idx位的下一位指向第k位,第k-1位的下一位指向idx
ne[k-1] = idx++; // 让idx增加
}
} for(int i=head ; i != -1; i = ne[i]) cout << e[i] << ' '; // 当i为-1说明到达了最后的节点,停止循环
return 0;
}

双向链表

实现一个双链表,双链表初始为空,支持 5 种操作:

  1. 在最左侧插入一个数;
  2. 在最右侧插入一个数;
  3. 将第 k 个插入的数删除;
  4. 在第 k 个插入的数左侧插入一个数;
  5. 在第 k 个插入的数右侧插入一个数

    现在要对该链表进行 M 次操作,进行完所有操作后,从左到右输出整个链表。

注意:题目中第 k 个插入的数并不是指当前链表的第 k 个数。例如操作过程中一共插入了 n 个数,则按照插入的时间顺序,这 n 个数依次为:第 1 个插入的数,第 2 个插入的数,…第 n 个插入的数。

输入格式

第一行包含整数 M,表示操作次数。

接下来 M 行,每行包含一个操作命令,操作命令可能为以下几种:

L x,表示在链表的最左端插入数 x。

R x,表示在链表的最右端插入数 x。

D k,表示将第 k 个插入的数删除。

IL k x,表示在第 k 个插入的数左侧插入一个数。

IR k x,表示在第 k 个插入的数右侧插入一个数。

输出格式

共一行,将整个链表从左到右输出。

数据范围

1≤M≤100000

所有操作保证合法。

输入样例:

10

R 7

D 1

L 3

IL 2 10

D 3

IL 2 7

L 8

R 9

IL 4 7

IR 2 2

输出样例:

8 7 7 3 2 9

算法原理

1.初始化左右指针数组lr,取两个虚拟节点表示链表的头和尾,头始终是0,尾始终是1,即r[0] = 1l[1] = 0idx因此也是从下标2开始。

2.5个操作细节看代码。

代码实现

需要强调的是,下标从2就开始存储的双向链表,在第k个位置处插入应表示为k-1+2,即k+1

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1000010 int e[N],l[N],r[N],idx; void init(){ // 初始化
l[1] = 0,r[0] = 1; //尾结点1的左边指向头节点下标0,头结点的右边指向尾结点下标1
idx = 2; // 从下标为2开始存储
} void Insert(int k,int x){ // 在第k个数(位置)后面插入
e[idx] = x;
l[idx] = k; // 插入的数的左边是第k个数
r[idx] = r[k]; // 插入的数右边是第k+1个数。
l[r[k]] = idx; // 第k个数的右边为idx
r[k] = idx++; // 第k+1个数的左边为idx,让idx增加一位存储下一个插入的数
} void remove(int k){ // 删除第k个数
r[l[k]] = r[k]; // 第k个数的左边的数指向第k个数的下一个位置
l[r[k]] = l[k]; // 第k个数的右边的数指向第k个数的上一个位置
} int main()
{
int n ;
cin >> n;
init();
while(n--){
string s;
int k,x;
cin >> s;
if(s=="L"){ // 头插法,在最左端插入
cin >> x;
Insert(0,x);
}
else if(s=="R"){ // 尾插法,在最右端插入
cin >> x;
Insert(l[1],x); // 最后一位的下一位插入一个数
}
else if(s=="IL"){ // 第k个数的左边插入一个数:注意:下标是从2开始的
cin >> k >> x;
Insert(l[k+1],x); // 从0开始的第k个数应插入的位置为k-1,而从2开始的是k-1+2,左边插入就变成l[k+1]
}
else if(s=="IR"){ // 第k个数右边插入一个数
cin >> k >> x;
Insert(k+1,x); // 同理在k+1处插入就是在第k个数后面插入
}
else{
cin >> k;
remove(k+1); // 同理,删除位置为k+1其实就是删除第k个数
}
}
for(int i=r[0]; i != 1; i=r[i]) cout << e[i] << " "; // 注意最右端的虚拟节点位置为1,到1就结束
cout << endl;
return 0;
}

2022-11-09 Acwing每日一题的更多相关文章

  1. CISP/CISA 每日一题 11

    CISA 每日一题(答) 一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓 ...

  2. CISP/CISA 每日一题 九(2017-11-30 09:25)

    电子银行风险管理责任: 1.风险管理是董事会和高级管理层的责任 2.实施技术是信息技术高级管理层的责任 3.测量和监控风险是经营管理层的责任     管理层在实施一个新的电子银行应用程序之前要 ___ ...

  3. 老男孩IT教育-每日一题汇总

    老男孩IT教育-每日一题汇总 第几天 第几周 日期 快速访问链接 第123天 第二十五周 2017年8月25日 出现Swap file….already exists以下错误如何解决? 第122天 2 ...

  4. ACM阶段总结(2016.10.07-2016.11.09)

    来这里也有一段时间了…… 总感觉自己练得不是很有效. 最近的一些行动就是不断做比赛,然后不停地补,但是感觉这样像只无头苍蝇,没有效果,学不到什么真正的东西. 最近开始打算补专题,做做codeforce ...

  5. CISP/CISA 每日一题 五

    CISA 每日一题(答) 信息系统审计师要确认系统变更程序中的: 1.变更需求应有授权.优先排序及跟踪机制: 2.日常工作手册中,明确指出紧急变更程序: 3.变更控制程序应同时为用户及项目开发组认可: ...

  6. [每日一题]ES6中为什么要使用Symbol?

    关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...

  7. [每日一题]面试官问:谈谈你对ES6的proxy的理解?

    [每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  8. 【js】Leetcode每日一题-完成所有工作的最短时间

    [js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...

  9. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  10. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

随机推荐

  1. Windows平台真实时毫秒级4K H264/H265直播技术方案

    背景 在刚提出4K视频的时候,大多数人都觉得没有必要,4K的出现,意味着更高的硬件规格和传输要求,1080P看的很爽.很清晰,完全满足了日常的需求.随着电视的尺寸越来越大,原本1080P成像已经无法满 ...

  2. KingbaseES图形化安装未弹出界面应该如何处理

      关键字: KingbaseES.X Windows.Gnome.DISPLAY 一.Linux下图形安装环境要求 1) 系统首先安装了X Windows的图形化支持软件包. 2) 系统安装了KDE ...

  3. 对表白墙js文件的解释

    index.js 1 Page({ 2 3 /** 4 * 页面的初始数据 5 */ 6 data: { 7 xcx_appid:"", 8 }, 9 HuoquDaohangLi ...

  4. 《吐血整理》高级系列教程-吃透Fiddler抓包教程(22)-如何使用Fiddler生成Jmeter脚本-下篇

    1.简介 今天这篇文章其实和上一篇差不多也是利用一个fiddler的插件进行Jmeter脚本的导出,开始宏哥想要合在一起写一篇文章,可是结果实践的时候,两个插件还是有区别的,因此为了不绕晕小伙伴或者童 ...

  5. ProxySQL的双层用户认证机制

    转载自:https://www.likecs.com/show-203802325.html 如果使用了ProxySQL来做中间路由,那么与我们平时登录数据库有一些区别:平时我们直接使用数据库的用户密 ...

  6. CI/CD集成

    文章转载自:https://kuboard.cn/guide/cicd/ 下图展示了当前比较典型的持续构建集成的一种做法. 在是否自动将最新版本部署到 Kubernetes 环境这个问题上,可能会有多 ...

  7. ELK Stack 日志平台性能优化

    转载自: https://mp.weixin.qq.com/s?__biz=MzAwNTM5Njk3Mw==&mid=2247487789&idx=1&sn=def0d8c2e ...

  8. js动态获取当前时间(年、月、日、上午/下午、时、分、秒)

    //获取动态时间function mytime() { var mydate = new Date(); var year = mydate.getFullYear(); var month = my ...

  9. this硬绑定

    一.this显示绑定 this显示绑定,顾名思义,它有别于this的隐式绑定,而隐式绑定必须要求一个对象内部包含一个指向某个函数的属性(或者某个对象或者上下文包含一个函数调用位置),并通过这个属性间接 ...

  10. Oracle索引和事务

    1. 什么是索引?有什么用? 1)索引是数据库对象之一,用于加快数据的检索,类似于书籍的目录.在数据库中索引可以减少数据库程序查询结果时需要读取的数据量,类似于在书籍中我们利用索引可以不用翻阅整本书即 ...