Description:
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.
分析:将位置从m到n的链表节点进行倒置,其余位置不变,要求不开辟新空间只遍历一次,注意m和n的范围是1-length。这题就时链表倒置的难度增加版本,我们需要首先遍历至m-1的位置,然后对接下来的链表进行转置n-m次,再重新链接链表即可。
代码如下:
/**
* 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 || !head->next || m == n)
return head;
ListNode new_head(0); //如果m=1的话 则需要一个头结点来记录
ListNode* ptr, *ptr1, *ptr2, *ptr3;
new_head.next = head;
ptr = &new_head; //ptr指针用于遍历至m-1的位置 保存信息
int pass = 0;
for(; pass < m - 1; pass++) //ptr遍历至m-1的位置
ptr = ptr->next;
ptr1 = ptr->next; //ptr1,ptr2,ptr3是用来对接下来链表进行倒置的
ptr2 = ptr1->next;
for(; pass < n - 1; pass++) //循环至ptr1为n-1位置时停止 此时已经完成了n位置的倒置 循环了n - m次
{
ptr3 = ptr2->next; //用ptr3保存ptr2下一个节点
ptr2->next = ptr1; //将ptr2下一个节点改为ptr1 完成倒置
ptr1 = ptr2; //ptr2成为新的ptr1
ptr2 =ptr3; //ptr3成为新的ptr2
}
ptr->next->next = ptr2; //ptr的节点指向位置为n的节点
ptr->next = ptr1; //位置为m的节点指向m后的节点(n=length时 ptr1 = NULL)
return new_head.next; //返回新的链表
}
};
在将链表转置的时候我们还可以使用递归dfs_reverse(ListNode* head, ListNode**tail, int count)这里设置一个tail是为了存储n+1的节点,**tail是使用二级指针存储一级指针,count是控制递归深度。
代码如下:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(!head || !head->next || m == n)
return head;
ListNode new_head(0);
ListNode* tmp;
new_head.next = head;
head = &new_head;
for(int i = 0; i < m - 1; i++)
head = head->next;
head->next = dfs_reverse(head->next, &tmp, n - m);
return new_head.next;
}
ListNode* dfs_reverse(ListNode* head, ListNode** tail, int count) //需要一个count来控制递归深度
{
if(count == 0)
{
*tail = head->next; //这里需要将n后面的链表节点传出来所以需要指针的指针
return head; //当然也可以设置一个节点Node然后将&Node传入再将n+1的节点位置
} // 用Node.next保存传出来
ListNode* tmp = dfs_reverse(head->next, tail, count - 1);
head->next->next = head;
head->next = *tail;
return tmp;
}
};