AcWing 827. 双链表
实现一个双链表,双链表初始为空,支持5种操作:
(1) 在最左侧插入一个数;
(2) 在最右侧插入一个数;
(3) 将第k个插入的数删除;
(4) 在第k个插入的数左侧插入一个数;
(5) 在第k个插入的数右侧插入一个数
现在要对该链表进行M次操作,进行完所有操作后,从左到右输出整个链表。
注意:题目中第k个插入的数并不是指当前链表的第k个数。例如操作过程中一共插入了n个数,则按照插入的时间顺序,这n个数依次为:第1个插入的数,第2个插入的数,…第n个插入的数。
输入格式
第一行包含整数M,表示操作次数。
接下来M行,每行包含一个操作命令,操作命令可能为以下几种:
扫描二维码关注公众号,回复:
12485797 查看本文章
(1) “L x”,表示在链表的最左端插入数x。
(2) “R x”,表示在链表的最右端插入数x。
(3) “D k”,表示将第k个插入的数删除。
(4) “IL k x”,表示在第k个插入的数左侧插入一个数。
(5) “IR k x”,表示在第k个插入的数右侧插入一个数。
输出格式
共一行,将整个链表从左到右输出。
数据范围
1≤M≤100000
所有操作保证合法。
#include<cstdio>
#include<cmath>
#include<ctime>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#define ll long long
#define ull unsigned long long
#define up_b upper_bound
#define low_b lower_bound
#define m_p make_pair
#define mem(a) memset(a,0,sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#define endl '\n'
#include<algorithm>
using namespace std;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar(); }
while('0'<=ch&&ch<='9') x=x*10+ch-'0', ch=getchar();
return f*x;
}
const int N = 1e5+5;
//l左指针, r右指针
int idx,e[N],l[N],r[N];
void init()
{
r[0]=1; l[1]=0; //0为左端点,1为右端点
idx=2; //编号从2开始
}
void insert(int k,int x) //在节点 k的右边插入一个数 x
{
e[idx]=x; l[idx]=k; r[idx]=r[k]; // idx的左边指向 k,右边指向 k 向右指向的位置
l[r[k]]=idx; // k右边的节点向左指向idx
r[k]=idx++; // k向右指向idx
}
void remove(int k) //删除 k节点
{
l[r[k]]=l[k]; //k右边的节点向左指向 k向左指向的位置
r[l[k]]=r[k]; //k左边的节点向右指向 k向右指向的位置
}
int main()
{
init();
int m; cin>>m;
string op; int x,k;
while(m--)
{
cin>>op;
if(op=="L")
{
cin>>x;
insert(0,x);
}
else if(op=="R")
{
cin>>x;
insert(l[1],x);
}
else if(op=="D")
{
cin>>k;
remove(k+1); //因为编号idx是从2开始的
}
else if(op=="IL")
{
cin>>k>>x;
insert(l[k+1],x); //在 k节点的左侧插入x 相当于 在 k左边节点的右侧插入x
}
else if(op=="IR")
{
cin>>k>>x;
insert(k+1,x);
}
}
for(int i=r[0];i!=1;i=r[i]) cout<<e[i]<<" ";cout<<endl; // 从左到右输出
// for(int i=l[1];i!=0;i=l[i]) cout<<e[i]<<" ";cout<<endl; // 从右到左输出
return 0;
}