Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given1->2->3->4->5->NULL, m = 2 and n = 4,
return1->4->3->2->5->NULL.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
/**
* 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)
return NULL;
ListNode *start = head, *end, *newS = NULL;
int pm = 2, pn = 1;
ListNode *p = head;
// 如果要逆转的第一个节点不是首节点,找到第一个要逆转的节点
if(m > 1)
{
pn = 2;
while(p && pm < m)
{
pm++;
pn++;
p = p->next;
}
newS = p; // 逆转前一段的末节点
start = p->next; // 第一个要逆转的节点
p->next = NULL; // 得到断开后的逆转前的一段
}
p = start;
while(p && pn < n)
{
pn++;
p = p->next;
}
end = p; // 要断开的末节点
ListNode *newE = end->next; // 断开后一段的首节点
end->next = NULL; // 断开,得到需要断开的段
ListNode *newH = reverse(start); // 逆转断开的段
ListNode *revE = findLast(newH); // 找到逆转后的末节点
// 将三段连接
revE->next = newE; // 连接断开的段与后面的段
if(newS) // 如果要断开的节点不是首节点
{
newS->next = newH;
return head;
}
else
return newH;
return head;
}
ListNode *reverse(ListNode *head)
{
if(!head || !head->next)
return head;
ListNode *next = head->next;
ListNode *newH = reverse(next);
next->next = head;
head->next = NULL;
return newH;
}
ListNode* findLast(ListNode *head)
{
if(!head || !head->next)
return head;
ListNode *p = head;
while(p && p->next)
{
p = p->next;
}
return p;
}
};