Reverse Linked List II
第一遍的做法:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(m==n) return head;
ListNode *tmp=head;
int len=n-m+1,rl=len;
while(--m)
{
tmp=tmp->next;
}
int *s=new int[len];
memset(s,0,sizeof(int)*len);
ListNode *mem=tmp;
while(len--)
{
s[len]=tmp->val;
tmp=tmp->next;
}
while(rl-1>len)
{
mem->val=s[++len];
mem=mem->next;
}
return head;
}
};
无脑申请了一个数组,然后通过数组的随机访问,对中间的区间进行重新赋值总而实现逆序。
确实就很无脑,但是对空间有一定的要求。
如果加上O(1)的空间限制做法可以参照如下:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode* new_head = new ListNode(0);
new_head -> next = head;
ListNode* pre = new_head;
for (int i = 0; i < m - 1; i++)
pre = pre -> next;
ListNode* cur = pre -> next;
for (int i = 0; i < n - m; i++) {
ListNode* move = cur -> next;
cur -> next = move -> next;
move -> next = pre -> next;
pre -> next = move;
}
return new_head -> next;
}
};
举个例子解释一下这个代码的思路:
把链表分为3个区间,前面区间->需要置换的区间->后面区间
假设"需要置换的区间"是1->2->3->4->5
整体为:前面区间->1->2->3->4->5->后面区间
进入(n-m)次循环,每次的操作为把 节点1 后面的那个节点放到"前面区间"的后面,即
第1次操作结果:前面区间->2->1->3->4->5->后面区间
第2次操作结果:前面区间->3->2->1->4->5->后面区间
第3次操作结果:前面区间->4->3->2->1->5->后面区间
第4次操作结果:前面区间->5->4->3->2->1->后面区间
结束。