双向链表练习题
题面:https://ac.nowcoder.com/acm/problem/53392
参考博客:https://blog.csdn.net/yjf_victor/article/details/101950122
本人一开始是用vector数组来按照题意一步步模拟的,最后提交后显示内存用超了...应该是在做翻转的时候比较耗时,并且需要频繁地做拼接操作。
vector(底层实现是数组):随机访问效率高,插入删除效率较低;
list(底层实现是链表):插入删除效率较低,随机访问效率较低;
对于此题,因为需要频繁做拼接操作,因此选用list更为合适。对于翻转的问题,上面大佬的博客中提供了一种解决方案:另外开一个反向表,将正向表的元素与反向表的元素对调,就相当与实现了反转。
例如:L:a=123 b=45
RL:a=321 b=54
l[a].splice(l[a].end(),l[b]):
L:a=12345 b=[]
RL:a=321 b=54
l_rev[b].splice(l_rev[b].end(),l_rev[a]):
L:a=12345 b=[]
RL:a=[] b=54321
swap(l[a],l_rev[b]);swap(l_rev[a],l_rev[b]):
L:a=54321 b=[]
RL:a=12345 b=[]
代码如下:
1 #include<iostream> 2 #include<list> 3 #include<algorithm> 4 using namespace std; 5 6 const int N=100010; 7 list<int> l[N]; 8 list<int> l_rev[N]; 9 list<int>::iterator it; 10 11 int main(){ 12 std::ios::sync_with_stdio(false); 13 14 int n,m; 15 while(cin>>n>>m){ 16 for(int i=1;i<=n;i++){ 17 l[i].clear(); 18 l[i].push_back(i); 19 20 l_rev[i].clear(); 21 l_rev[i].push_back(i); 22 } 23 while(m--){ 24 int a,b; 25 cin>>a>>b; 26 l[a].splice(l[a].end(),l[b]); 27 l_rev[b].splice(l_rev[b].end(),l_rev[a]); 28 swap(l[a],l_rev[b]); 29 swap(l_rev[a],l_rev[b]); 30 } 31 cout<<l[1].size()<<" "; 32 for(it=l[1].begin();it!=l[1].end();it++) cout<<*it<<" "; 33 cout<<endl; 34 } 35 36 return 0; 37 }
关于list中的splice函数的用法参考这位大佬的博客:https://www.cnblogs.com/joelwang/p/10911758.html