【链表】206. Reverse Linked List; 92. Reverse Linked List II;25. Reverse Nodes in k-Group

参考:labuladong 递归反转链表的一部分

labubadong 如何k个一组反转链表

问题:

206.链表反转。

Example:

Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL

  

92.指定区间链表反转。

Note: 1 ≤ m ≤ n ≤ length of list.

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL

  

25. 每连续k个元素进行反转。
Example 1:
Input: head = [1,2,3,4,5], k = 2
Output: [2,1,4,3,5]

Example 2:
Input: head = [1,2,3,4,5], k = 3
Output: [3,2,1,4,5]

Example 3:
Input: head = [1,2,3,4,5], k = 1
Output: [1,2,3,4,5]

Example 4:
Input: head = [1], k = 1
Output: [1]
 
Constraints:
The number of nodes in the list is in the range sz.
1 <= sz <= 5000
0 <= Node.val <= 1000
1 <= k <= sz

   

解法:Recursion(递归)Iteration(迭代)

206.

1.递归获得2~6,反转后的结果。

2.将2->next指针,指向1: 

由于原来1->next=2,因此 (1->next)->next = 1

3.将1->next指向NULL

 

 

BASE:

只有一个节点 or 0个节点,return head

代码参考:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode() : val(0), next(nullptr) {}
 7  *     ListNode(int x) : val(x), next(nullptr) {}
 8  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 9  * };
10  */
11 class Solution {
12 public:
13     //1->reverseList(2<-3<-4<-5)
14     ListNode* reverseList(ListNode* head) {
15         //base
16         if(!head || !head->next) return head;
17         //recursion
18         ListNode* newhead = reverseList(head->next);
19         //OPT
20         head->next->next = head;
21         head->next = nullptr;
22         return newhead;
23     }
24 };

 

92.

先解决,如何反转前n个节点。

reverseN(ListNode* head, int n)

相较于206,多了第n个节点之后的,不需要反转的节点successor

因此,比206多出的处理:

  • ★BASE:
    • 记录successor节点,n==1的时候,只剩一个节点
    • successor = head->next
  • recursion后的 ★OPT:
    • head->next=successor

即,代码为:

 1     ListNode* reverseN(ListNode* head, int n) {
 2         //base
 3         if(n==1) {
 4             successor = head->next;//★BASE
 5             return head;
 6         }
 7         //recursion
 8         ListNode* newhead = reverseN(head->next, n-1);
 9         //OPT
10         head->next->next = head;
11         head->next = successor;//★OPT
12         return newhead;
13     }

 

接下来,解决 从第m个开始,

递归到m==1,则变成上面的问题,直接调用reverseN即可。

其他情况,依次递归,不用更改任何指针。

⚠️ 注意:从第0个移动到第m个时的递归中,

返回值:当前的新头。所以,head->next=上次递归的结果。

代码为:

1     ListNode* reverseBetween(ListNode* head, int m, int n) {
2         if(!head || !head->next) return head;
3         if(m==1) return reverseN(head, n);
4         head->next = reverseBetween(head->next, m-1, n-1);
5         return head;
6     }

 

代码参考:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode() : val(0), next(nullptr) {}
 7  *     ListNode(int x) : val(x), next(nullptr) {}
 8  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 9  * };
10  */
11 class Solution {
12 public:
13     ListNode* successor;
14     ListNode* reverseBetween(ListNode* head, int m, int n) {
15         if(!head || !head->next) return head;
16         if(m==1) return reverseN(head, n);
17         head->next = reverseBetween(head->next, m-1, n-1);
18         return head;
19     }
20     ListNode* reverseN(ListNode* head, int n) {
21         //base
22         if(n==1) {
23             successor = head->next;
24             return head;
25         }
26         //recursion
27         ListNode* newhead = reverseN(head->next, n-1);
28         //OPT
29         head->next->next = head;
30         head->next = successor;
31         return newhead;
32     }
33 };

 

25. 
用迭代(Iteration)的方法实现[a,b)的反转
如下图,反转 [1,NULL)

 

 

 1     ListNode* reverse(ListNode* a, ListNode* b) {
 2         ListNode *cur = a, *pre = NULL, *nxt = a;
 3         while(cur!=b) {
 4             nxt = cur->next;
 5             cur->next = pre;
 6             pre = cur;
 7             cur = nxt;
 8         }
 9         return pre;
10     }

再用递归,求出第一组[a,b)反转后,连接到后面[b,...)已经反转完成的所有。

如下图k=2,[1,3)

 ⚠️ 注意:如果不足k个元素,则不进行反转。

 1     ListNode* reverseKGroup(ListNode* head, int k) {
 2         if(!head) return head;
 3         ListNode *a=head, *b=head;
 4         for(int i=0; i<k; i++) {
 5             if(b==NULL) return head;//不足k个元素,不进行反转
 6             b = b->next;
 7         }
 8         //反转[a,b)
 9         ListNode* newhead = reverse(a, b);
10         //连接反转后的[a,b),和反转的后面所有元素[b,...)
11         a->next = reverseKGroup(b, k);
12         return newhead;
13     }

完整代码参考:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode() : val(0), next(nullptr) {}
 7  *     ListNode(int x) : val(x), next(nullptr) {}
 8  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 9  * };
10  */
11 class Solution {
12 public:
13     //[a,b) -> [a,NULL)
14     ListNode* reverse(ListNode* a, ListNode* b) {
15         ListNode *cur = a, *pre = NULL, *nxt = a;
16         while(cur!=b) {
17             nxt = cur->next;
18             cur->next = pre;
19             pre = cur;
20             cur = nxt;
21         }
22         return pre;
23     }
24     ListNode* reverseKGroup(ListNode* head, int k) {
25         if(!head) return head;
26         ListNode *a=head, *b=head;
27         for(int i=0; i<k; i++) {
28             if(b==NULL) return head;
29             b = b->next;
30         }
31         ListNode* newhead = reverse(a, b);
32         a->next = reverseKGroup(b, k);
33         return newhead;
34     }
35 };

 

posted @ 2020-10-01 20:55  habibah_chang  阅读(132)  评论(0编辑  收藏  举报