【链表】206. Reverse Linked List; 92. Reverse Linked List II

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

问题:

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

  

解法:Recursion(递归)

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 };
原文地址:https://www.cnblogs.com/habibah-chang/p/13759069.html