这道leetcode题,看起来是十分简单的
但解决过程中,分类有些问题
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
.
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n)
{
//
if(m==n)return head;
ListNode* iter;
ListNode *pre = new ListNode(0);
//头结点去除一般性
auto pre_s =pre;
pre->next = head;
iter = pre;
for(int i=0;i<m-1;i++)
pre = pre->next;
auto preNext=pre->next;
for(int i=0;i<n;i++)
iter=iter->next;
//刚好移到 tail Node pointer* 位
if(iter->next!=NULL)
{
auto iterNext = iter->next;
rLink(preNext,iter);
pre->next = iter;
preNext->next = iterNext;
return pre_s->next;
}else{
rLink(preNext,iter);
pre->next =iter;
preNext->next = NULL;
return pre_s->next;
}
}
void rLink(ListNode* start,ListNode* tail)
{
ListNode* s =start;
ListNode* g = s->next;
if(g==tail)
{
tail->next = start;
}
else{
ListNode* gnext = g->next;
//考虑特例情况
while(g!=tail)
{
g->next =s;
s = g;
g = gnext;
gnext = gnext->next;
}
g->next = s;
}
}
};
问题在这成立!//////////////
加了前置结点后,head结点被一般化后,返回一定要prehead->next;因为head节点的一般性导致他是有可能改变的,也会被反转
第二点,反转链表时如果不用二级指针是要用三个一级指针来实现的算法一定要熟悉
一般例子的驱动要记牢,跑一遍逻辑才会理通,刷题通理。
ListNode *reverseBetween(ListNode *head, int m, int n)
{ if(m==n)return head;
n-=m;
ListNode prehead(0);
prehead.next=head;
ListNode* pre=&prehead;
while(--m)pre=pre->next;
ListNode* pstart=pre->next;
while(n--)
{ ListNode *p=pstart->next;
pstart->next=p->next;
p->next=pre->next;
pre->next=p; }
return prehead.next; }
主要思想如下:找到这个点后使用cur和move把move头插到pre->next到cur这个链表中
实现了reverse局部链表。
思想主要时倒插,实现倒排序!