1025 反转链表 (25 分)
题目链接:1025 反转链表 (25 分)
这道题目花费了很长时间,主要是最近事情太多,没有集中精力想这道题目。
起初我将address和Next按照字符串处理,这样处理的好处是不用考虑整数的前导0。但是提交后有一个测试点超时,
我赶紧将cout换成printf,将输出的字符串进行.c_str();再一次提交,没有超时,AC!。但是字符串我还是很生疏的,
我不小心将cin.ignore();删除之后,程序继续超时,字符串的输入输出及其基本操作我还是很迷的。暂且搁置,以后
好好整理,于是我将输入输出换成整数int,又重新捋了一下逻辑。
假定要求反转区间长度为k,该程序设置了一个计数器i,初值为0,每当访问一个结点,计数器++,每当k是i的整数倍时,
对区间k个结点进行反转。具体反转进行一下操作。
1、newhead记录本次反转之后的区间的新的首元结点,若不是第一次反转,将上一区间的尾元结点与新的首元结点连接,即连接两个区间。
newtail记录区间调整后的尾元结点,end记录尾元结点的下一个结点,当作区间for循环的终止条件。如果是第一次进行调整,则更新整个链表的
首元结点。
2、对区间进行调整的思想如下
temp的初值记录紧跟着本曲间的第一个结点,进行区间反转时,从原区间的head开始,到head为止(不包含end),依次更新其Next。特别注意,
在更行每一个address的Next之前记录其Next(next记录),不然不能按照原区间顺序进行更新。另外head的Next应当更新为temp的初值。更新完
毕后记着更新head,每一次区间调整的head即为上一次的end,第一个的head为first。
3、最后输出的时候注意-1的特殊情况。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct Node 5 { 6 int Data,Next; 7 }a; 8 map<int,Node> m; 9 int main() 10 { 11 int address,next,first,head,end,tail,newhead,newtail,add,data,n,k; 12 scanf("%d %d %d",&first,&n,&k);//结点总个数n,要求反转的结点数k 13 newtail=-2; 14 for(int i=1;i<=n;i++) 15 { 16 scanf("%d %d %d",&address,&a.Data,&a.Next); 17 m[address]=a; 18 } 19 int i=0; 20 head=first; 21 for(address=first;address!=-1;address=m[address].Next) 22 { 23 i++; 24 if(i%k==0) 25 { 26 newhead=address; //区间调整后的首结点 27 if(newtail!=-2) 28 m[newtail].Next=newhead; 29 newtail=head; //区间调整后的尾结点 30 end=m[address].Next; 31 address=newtail; //区间调整后的最后一个结点,避免影响for循环逻辑 32 if(i/k==1) 33 first=newhead; //如果是第一次进行调整,更新新的首元结点 34 int temp=end; //temp初值记录原区间尾元结点的Next 35 //从原来的第一个结点开始,依次调整它们的Next,注意新区间的首元结点的Next应当调整为原区间尾元结点的Next。 36 for(add=head;add!=end;temp=add,add=next) 37 { 38 next=m[add].Next; 39 m[add].Next=temp; 40 } 41 head=end;//head记录没有调整的区间的第一个结点的地址。 42 } 43 } 44 for(address=first;address!=-1;address=m[address].Next) 45 if(m[address].Next!=-1) 46 printf("%05d %d %05d\n",address,m[address].Data,m[address].Next); 47 else 48 printf("%05d %d %d\n",address,m[address].Data,m[address].Next); 49 return 0; 50 } 51 /* 52 00100 6 3 53 00000 4 99999 54 00100 1 12309 55 68237 6 -1 56 33218 3 00000 57 99999 5 68237 58 12309 2 33218 59 */