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.
算法思路:
这就是一个单链表就地逆置问题,只要先找到需要逆置的一段的头尾结点就可以进行操作了。
但是,
使用我之前学习到的单链表就地逆置算法就会Time limit exceed,我很伤心.....
可恶啊~~~
所以我不得不借鉴Discussion area的一些大神的算法了。。
/**
* 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 == NULL) return NULL;
ListNode *dummy = new ListNode(0); // create a dummy node to mark the head of this list
dummy->next = head;
ListNode *pre = dummy; // make a pointer pre as a marker for the node before reversing
for(int i = 0; i<m-1; i++) pre = pre->next;
ListNode *start = pre->next; // a pointer to the beginning of a sub-list that will be reversed
ListNode *then = start->next; // a pointer to a node that will be reversed
// 1 - 2 -3 - 4 - 5 ; m=2; n =4 ---> pre = 1, start = 2, then = 3
// dummy-> 1 -> 2 -> 3 -> 4 -> 5
for(int i=0; i<n-m; i++)
{
start->next = then->next;
then->next = pre->next;
pre->next = then;
then = start->next;
}
// first reversing : dummy->1 - 3 - 2 - 4 - 5; pre = 1, start = 2, then = 4
// second reversing: dummy->1 - 4 - 3 - 2 - 5; pre = 1, start = 2, then = 5 (finish)
return dummy->next;
/* ListNode* fakehead=new ListNode(0);
fakehead->next=head;
ListNode* p1=fakehead;
ListNode* ps=head;
ListNode *s1=head,*s2;
ListNode *pre,*d;
if(m==n)
return head;
if(!head||!head->next)
return head;
while(m!=1)
{
m--;
pre=s1;
s1=s1->next;
}
ListNode *temp;
s2=temp=s1;
pre->next=NULL;
for(int i=1;i<=n-m;i++)
s2=s2->next;
ListNode *q=s2;
for(int i=1;i<n-m;i++)
{
d=s1;
s1=s1->next;
d->next=pre->next;
pre->next=d;
}
temp->next=q;
return fakehead->next;*/
}
};
被注释了的是我的算法。。。