LeetCode 92. Reverse Linked List II
将链表分成三段,中间一段reverse后再链接。
链表中节点位置从1开始计数。
注意m可能为1,所以要加上if(last == start) head = end; 不然会丢失数据,因为reverse后head是reverse一段的最后一节点,只返回head的话head之前的节点全部丢失。
4ms
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* reverseBetween(ListNode* head, int m, int n) { 12 int cnt = 1; 13 14 //order: last->start(m)->...->end(n)->next 15 ListNode* start = head; 16 ListNode* last = start; 17 while(cnt != m){ 18 last = start; 19 start = start->next; 20 ++cnt; 21 } 22 ListNode* end = start; 23 24 while(cnt != n){ 25 end = end->next; 26 ++cnt; 27 } 28 ListNode* next = end->next; 29 end->next = NULL; 30 31 //reverse 32 ListNode* prev = NULL, * cur = start; 33 while(cur){ 34 ListNode* tmp = cur->next; 35 cur->next = prev; 36 prev = cur; 37 cur = tmp; 38 } 39 40 41 //link 42 last->next = end; 43 start->next = next; 44 if(last == start) head = end; 45 return head; 46 47 } 48 };
另有迭代算法,0ms。
另开一个节点node,指针为p2,这个节点的作用是帮助reverse。
把list想象成三段,首先使p1为第二段(即需要reverse的一段)的head。注意在这之前prev = NULL,这样如果m = 1,就不进入while循环,prev就会保持NULL;如果m!=1,prev就等于第一段的最后一个节点,在之后可根据prev是否为NULL将head设为不同的值。
然后将第二段reverse,在while的每个循环内,先将p2插到p1前(p2->next = p1;),然后p2->next->next = tmp; 接着p1跳到下一个节点。把p2想成一个list的head,每次将p1节点插到p2的下一个节点(使p2->next = p1)。
1 while(p1 && n-- > 0){ 2 ListNode* tmp = p2->next; 3 p2->next = p1; 4 p1 = p1->next; 5 p2->next->next = tmp; 6 } 7 //p2:virtual node; p2->next: head of reversed list; p1:head of the third part of original list
最后把三段连接起来。
完整代码:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode* reverseBetween(ListNode* head, int m, int n) { 12 ListNode* p1 = head; 13 ListNode node(0); 14 ListNode* p2 = &node; 15 ListNode* prev = NULL; 16 while(p1 && --m > 0) 17 { 18 prev = p1; 19 p1 = p1->next; 20 n--; 21 } 22 //p1: start of reverse list 23 24 25 26 while(p1 && n-- > 0) 27 { 28 ListNode* tmp = p2->next; 29 p2->next = p1; 30 p1 = p1->next; 31 p2->next->next = tmp; 32 } 33 //p2:virtual node; p2->next: head of reversed list; p1:head of the third part of original list 34 35 36 if(prev) 37 prev->next = node.next; 38 else//prev == NULL if m = 1 39 head = node.next; 40 41 while(p2->next) 42 p2 = p2->next; 43 p2->next = p1; 44 return head; 45 } 46 };