LeetCode92. 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:
思路
首先根据m和n找到链表需要逆转的部分的头的前一个位置和尾的前一个位置,设为pBegin和pEnd(考虑到头结点前面没有结点,所以我们需要设置一个虚假头结点fake,使fake->next=head),初始化都指向fake。
ListNode* fake=new ListNode(0);
fake->next = head;
ListNode *pBegin=fake, *pEnd=fake;
int distance = n - m ;
while(pEnd && distance>0){
pEnd = pEnd->next;
distance--;
}
while(pBegin && pEnd && m-1>0) {
pBegin = pBegin->next;
pEnd = pEnd->next;
m--;
}
然后设置一个p结点指向需逆转部分的头结点(p=pBegin->next),设置一个q结点指向需逆转部分的尾结点的后一结点(p=pEnd->next->next),并设置逆转后部分链表的头结点pHead,p插到原始q的后面,头结点pHead和p依次后移,直到p==q为止(具体看代码和图片(手绘……))
ListNode *p = pBegin->next;
ListNode *q = pEnd->next->next;
ListNode *pHead = q;
while(p != q){
ListNode* node = p->next;
p->next = pHead;
pHead = p;
p = node;
}
最后将逆转部分的链表接入原链表
pBegin->next = pHead;
代码实现
/**
* 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 || m>=n) return head;
ListNode* fake=new ListNode(0);
fake->next = head;
ListNode *pBegin=fake, *pEnd=fake;
int distance = n - m ;
while(pEnd && distance>0){
pEnd = pEnd->next;
distance--;
}
while(pBegin && pEnd && m-1>0) {
pBegin = pBegin->next;
pEnd = pEnd->next;
m--;
}
if (pBegin==NULL || pEnd==NULL || pEnd->next == NULL){
return head;
}
ListNode *p = pBegin->next;
ListNode *q = pEnd->next->next;
ListNode *pHead = q;
while(p != q){
ListNode* node = p->next;
p->next = pHead;
pHead = p;
p = node;
}
pBegin->next = pHead;
return fake->next;
}
};