反转指定两个位置之间的树。
ListNode *reverseBetween(ListNode *head, int m, int n) {
if(m==n)return head;
n-=m;
ListNode prehead(0);
prehead.next=head;
ListNode* pre=&prehead;
while(--m)pre=pre->next;
ListNode* pstart=pre->next;
while(n--)
{
ListNode *p=pstart->next;
pstart->next=p->next;
p->next=pre->next;
pre->next=p;
}
return prehead.next;
}
找到反转起始 pstart,起始前一个 pre。
然后再反转 n-m+1个数即可,反转循环一次反转2个数,所以要循环n-m次即可,故 while (n-m)。
我的程序:有点繁琐,时间很快,3ms。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(head==NULL || head->next==NULL ||m==n) return head;
ListNode *p,*pfirst,*p1,*q,*qend,*tmp;
//p1=new ListNode(0);
p1=new ListNode(0);
ListNode *start=p1;
p1->next=head;
for(int i=0;i<m-1;i++){
p1=p1->next;
}
pfirst=p1;
p=p1->next;
q=p1->next;
for(int i=m;i<n;i++){
q=q->next;
}
qend=q->next;
q->next=NULL;
tmp=reverseList(p);
pfirst->next=tmp;
while(tmp->next){
tmp=tmp->next;
}
tmp->next=qend;
return start->next;
}
ListNode* reverseList(ListNode* head) {
if(head==NULL || head->next==NULL) return head;
ListNode* p1=head;
ListNode* p2=head->next;
ListNode* p3;
//p=head->next;
while(p2){
p3=p2->next;
p2->next=p1;
p1=p2;
p2=p3;
}
head->next=NULL;
return p1;
}
};