题目
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
分析
使用头插法进行反转,也就是不断地将需要反转的节点插在前面。为了方便,我们新建一个哨兵节点,指向头节点。如下图:
然后我们需要记录:头节点,当前节点的前一个节点,当前节点三个节点的位置。如图:
这道题还有几个边界问题需要考虑:
1.m=n的情况 返回原链表
2. head为空
3. 当n=链表长度的时候,需要额外判断再进行判断。
4.头插法涉及两个节点,所以计数的时候需要考虑情况。
ListNode* reverseBetween(ListNode* head, int m, int n) {
int ans=1;
if(head==NULL)
return NULL;
if(m==n)
return head;
ListNode *Head=new ListNode(NULL);
Head->next=head;
ListNode *phead=Head;
ListNode *pre=phead->next;
ListNode *pcur=pre->next;
while(pcur->next!=NULL)
{
if(ans<m)
{
phead=phead->next;
pre=phead->next;
pcur=pre->next;
ans++;
}
//pre本身也是反转节点 所以等于n会多反转一个节点
else if(ans>=m&&ans<n)
{
pre->next=pcur->next;
pcur->next=phead->next;
phead->next=pcur;
pcur=pre->next;
ans++;
}
else
{
break;
}
}
if(n>ans)//说明最后一个节点也需要反转
{
pre->next=NULL;
pcur->next=phead->next;
phead->next=pcur;
}
Head=Head->next;
return Head;
}