難度中等325
反轉從位置 m 到 n 的鏈表。請使用一趟掃描完成反轉。
說明:
1 ≤ m ≤ n ≤ 鏈表長度。
示例:
輸入: 1->2->3->4->5->NULL, m = 2, n = 4
輸出: 1->4->3->2->5->NULL
步驟:
1.創建一個空節點res,將head置與其後面
2.記錄反轉區間的第一個節點和其前一個節點 1 2
3. 對反轉區間的元素進行反轉
4.將反轉後剩下的的節點(4 5)與步驟2的兩個節點連接
5.返回res.next(存res的目的是實現在head也被反轉的情況下也可以從頭輸出)
/**
* 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) {
ListNode* p=new ListNode(0);
p->next=head;
ListNode* res=p;
for(int i=0;i<m-1;i++){
p=p->next;
}
//兩個連接處的節點
ListNode* x1=p;//1
ListNode* x2=p->next;//2
int count=n-m;
ListNode* pre=x2;//2
ListNode* cur=x2->next;//3
while(count--){
ListNode* nex=cur->next;
cur->next=pre;
pre=cur;
cur=nex;
}//pre 4 cur 5
x1->next=pre;//1 4
x2->next=cur;//2 5
return res->next;
}
};
遞歸解決辦法:
class Solution {
public:
ListNode* reverse(ListNode* x,ListNode* y){
if(!y)
return x;
ListNode* nex=y->next;
y->next=x;
return reverse(y,nex);
}
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode* res=new ListNode(0);
ListNode* p=res;
p->next=head;
for(int i=0;i<m-1;i++){
p=p->next;
}
ListNode* x=p;//1
ListNode* st=p->next;//2
for(int i=1;i<=n-m+1;i++){
p=p->next;
}//p 4
ListNode* ed=p;//4
ListNode* y=p->next;//5
ed->next=NULL;
x->next=reverse(NULL,st);//1 4
st->next=y;//2 5
return res->next;
}
};