1. 题目描述
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
2.代码如下
//2019-04-22
typedef struct ListNode node;
struct ListNode* reverseBetween(struct ListNode* head, int m, int n)
{
if((m == n )||(head->next == NULL)||(head == NULL))
{
return head;
}
node *ptemp = head;
node *ppre = NULL;
node *pafter = NULL;
node *pm = NULL;
node *pn = NULL;
int i = 1;
pn = pm = head;
while(i < m)
{
ppre = ptemp;
ptemp = ptemp->next;
pm = ptemp;
i++;
}
while(i < n)
{
ptemp = ptemp->next;
pn = ptemp;
pafter = pn->next;
i++;
}
node *temp = NULL;
node *pmflag = pm;
node *pnflag = pn;
node *pnewhead = (node*)malloc(sizeof(node));
memset(pnewhead,0,sizeof(node));
if(pm&&pn)
{
ptemp = pm;
temp = ptemp->next;
while(ptemp != pafter)
{
ptemp->next = pnewhead;
pnewhead = ptemp;
ptemp = temp;
if(temp!=NULL)
{
temp = temp->next;
}
}
pmflag->next = pafter;
if(ppre != NULL)
{//m!=1
ppre->next = pnewhead;
}
else
{//m == 1
head = pnflag;
}
}
return head;
}
//2021-03-18
struct ListNode* reverseBetween(struct ListNode* head, int left, int right){
typedef struct ListNode Node;
Node *pre_left = NULL;
Node *pleft = head;
Node *pright = head;
Node *pnext_right = NULL;
if (!head || !head->next || right == left)
{
return head;
}
int cnt = 1;
while (cnt < left)//得到要逆转的子链表的头结点指针和其头结点的前驱
{
pre_left = pleft;
pleft = pleft->next;
cnt++;
}
cnt = 1;
pnext_right = pright->next;
while (cnt < right)//得到要逆转的子链表的尾结点指针和其尾结点的后继
{
pright = pright->next;
if (pright)
{
pnext_right = pright->next;
}
cnt++;
}
pright->next = NULL;//断开:子链表后尾元素指向NULL
Node *ptmp = NULL;
Node *pnewsublist = NULL;
Node *psubtail = NULL;
while(pleft)//逆转子链表
{
if (pnewsublist)
{
ptmp = pleft;
pleft = pleft->next;
ptmp->next = pnewsublist;
pnewsublist = ptmp;
}
else
{
psubtail = pnewsublist = pleft;
pleft = pleft->next;
}
}
if (pre_left == NULL)//left==1
{
psubtail->next = pnext_right;
return pnewsublist;
}
pre_left->next = pnewsublist;//子链表左边接入
if (psubtail)//子链表右边接入
{
psubtail->next = pnext_right;
}
return head;
}