92. 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.
分析
这个题目和直接翻转链表类似,麻烦的地方就是定位出需要翻转链表的头和尾,要注意的条件特别多。请看源码
源码
/**
* 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;
if(head->next == NULL) return head;
if(m == n || n < 2) return head; // m <= n m=n时不需要翻转,n<2时即m=n=1也不需要翻转
//定位需要翻转链表的头尾指针以及头指针的前一个指针,尾指针的后一个指针
ListNode *pmPre = NULL, *pm = NULL, *pn = NULL,*pnNext = NULL;
ListNode *pList = head;
int i = 1;
while(i <= (n+1)) {
if(i == (m-1))pmPre = pList; // m = 1时,说明链表第一个元素开始,那头指针前面元素就是空指针了
if(i == m)pm = pList;
if(i == n)pn = pList;
if(i == n+1)pnNext = pList; // 尾指针后一个指针
i++;
if(pList)pList = pList->next;
}
// 为了翻转指针,先将尾指针的next置空
pn->next = NULL;
reverseList(pm); // 递归翻转指针
if(pmPre) // 如果pmPre不为空,将pmPre的下一个元素置成翻转后的第一个元素
pmPre->next = pn;
pm->next = pnNext; // 将翻转后的尾指着的next置成pnNext
return m == 1 ? pn : head;
}
ListNode* reverseList(ListNode* head) {
if(!head)return NULL;
if(head->next == NULL)return head;
ListNode* pNode = head->next;
ListNode* pHead = reverseList(pNode);
pNode->next = head;
head->next = NULL;
return pHead;
}
};