双向链表练习题

题面: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

posted @ 2020-05-01 18:33  lucky99  阅读(449)  评论(0编辑  收藏  举报