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.
题意:将链表中的部分进行反转。
法一:先让指针p遍历一遍m至n的结点数据,并将这些数据保存在一个临时数组temp中。接着让指针q再遍历一次,将刚刚数组temp中的数据从尾到头插入到m至n。
class Solution {
public:
ListNode *reverseBetween(ListNode *head, int m, int n) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(!head)
return NULL;
ListNode *p=head,*q=head;
int i=1;
for(;i<m;i++)
{
p=p->next;
q=q->next;
}
int *temp=new int[n-m+1];
for(;i<=n;i++)
{
temp[i-m]=p->val;
p=p->next;
}
for(i=m;i<=n;i++)
{
q->val=temp[n-i];
q=q->next;
}
delete []temp;
return head;
}
};
法二:一次遍历的方法
1.查找到m节点的前一节点了pleft,m节点pre,m的下一节点pNode。
2.在m-n范围内进行反转。
3.将pleft的下一节点指为n节点,原本的m节点下一节点指为n的后一节点。
4.要注意各种节点的非空判断,这个边界条件要非常注意,解决此题的难点就在这。
class Solution {
public:
ListNode *reverseBetween(ListNode *head, int m, int n) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(head==NULL)
return NULL;
if(m==n)
return head;
ListNode *pre=NULL;
ListNode *pNode=NULL;
ListNode *pleft=NULL; //节点m的左邻节点
for(int i=1;i<m;i++)
{
if(i==1)
pleft=head;
else
pleft=pleft->next;
}
pre=pleft;
if(pleft)
pNode=pleft->next;
else
pNode=head;
int len =n-m;
ListNode *plat=pNode;
if(pre)
pre=pre->next;
else
pre=head;
pNode=pNode->next;
while(pNode!=NULL&&len--)
{
ListNode *pNext=pNode->next;
pNode->next=pre;
pre=pNode;
pNode=pNext;
}
if(pNode)
plat->next=pNode;
else
plat->next=NULL;
if(pleft)
pleft->next=pre;
else
head=pre;
return head;
}
};