题目链接:http://oj.leetcode.com/problems/reverse-linked-list-ii/
题目内容:
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL
, m = 2 and n = 4,
return 1->4->3->2->5->NULL
.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
这问题就是把一个链表的m---n位倒序,
乍一看就照着四个指针开始写了,一个*phead指向m的前一结点,*pend指向n的后一结点,
对于逆转单向链表同时需要三个指针*pi,*pj,*pend从*pstart开始,依次调转。
(ps:这个题很久以前貌似看过。)
没仔细想就开始写,写完了,突然考虑特殊情况,比如m=1,n=end,相当于把整个链表调换,这样pstart和pend就会为空,这样就要处理好多种特殊情况啊。。。突然灵光一闪(好像以前看过类似解法):
在原始列表的头尾各加一个结点,如:
myhead->1->2->3->4->5->mytail->NULL
这样只需要处理链表长度为1和m==n的情况了!
代码虽然可读性不是特别强。但是还是放上来吧,希望对有些同学有帮助~
class Solution {
public:
ListNode *reverseBetween(ListNode *head, int m, int n) {
ListNode *pstart,*pi,*pj,*pend;
ListNode mystart(0),myend(0);
//int count=1;
if (head->next==NULL || m==n)
return head;
//add head,tail
pstart=&mystart;
mystart.next=head;
pend=head;
while (pend->next){
//count++;
pend=pend->next;
}
pend->next=&myend;
m++;n++;
//find pstart
for (int i=2;i<m;i++){
if (pstart->next!=NULL)
pstart=pstart->next;
}
//init pi,pj,pend;
pi=pstart;
if (pi->next!=&myend)
pj=pi->next;
if (pj->next!=&myend)
pend=pj->next;
pj->next=NULL;
for (int i=m;i<n;i++){
pi=pj;
pj=pend;
pend=pend->next;
pj->next=pi;
}
pstart->next=pj;
while (pi->next)
pi=pi->next;
if (pi->next!=&myend){
pi->next=pend;
while (pi->next!=&myend)
pi=pi->next;
pi->next=NULL;
}
return mystart.next;
}
};