题目描述
小红拿到了一个数组,初始数组为空,她希望你实现以下两种操作:
1. 输入1 x y,将x插入在元素y的右边。保证此时数组中没有元素等于x,且数组中存在一个y。特殊的,如果将x插入在数组的最左边,则y=0
2. 输入2 x,将元素x删除。
请你在所有操作后输出整个数组。
输入描述:
第一行输入一个正整数q,代表操作次数。 接下来的q行,每行输入两个整数2 x或者三个整数1 x y,代表一次操作。操作含义如题目说明。 1≤q≤2×10^5 1≤x≤10^9 0≤y≤10^9
输出描述:
第一行输出一个整数n,代表最终数组的大小。 第二行输出n个正整数,代表最终的数组。
示例1
输入
4 1 2 0 1 7 2 1 1000 7 2 7
输出
2 2 1000
说明
第 1 次操作后,数组为[2]。 第 2 次操作后,数组为[2,7]。 第 3 次操作后,数组为[2,7,1000]。 第 4 次操作后,数组为[2,1000]。
AC代码:
#include<iostream>
#include<map>
using namespace std;
//多开一位后边用
const int N = 1e9+1;
int main()
{
//快读
ios::sync_with_stdio(false);
cin.tie(nullptr);
int q,ans=0;
cin >> q;
//这里用key值去存当前数,value存所指向的下一个点的数
map<int,int> l,r;
//当作两个哨兵分别为头结点,尾结点
r[0] = N , l[N] = 0;
while(q--)
{
int op;
cin >> op;
if(op == 1)
{
int x,y;
cin >> x >> y;
int left = y,right = r[y];
//想先去把指向指到要插入的两边,再去改变两边指向
r[x] = right,l[x] = left;
r[left] = x,l[right] = x;
ans++;
}
else
{
int x;
cin >> x;
r[l[x]] = r[x];
l[r[x]] = l[x];
ans--;
}
}
cout << ans << endl;
for(int i=r[0];i!=N;i=r[i]) cout << i << ' ';
return 0;
}
这里的map用的很巧妙,unordered_map也可以,可以手动多模拟两遍,注意键值对表示的都是什么