• 【链表】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 };
  • 相关阅读:
    JimuReport积木报表 v1.4.3版本发布,免费的可视化低代码报表
    2022国内低代码平台厂商排行榜—经典收藏
    sql server2005 无法修改表,超时时间已到 在操作完成之前超时时
    试下C# 8.0 的switch表达式 (VS2019)
    vue项目部署在IIS上面的心得
    使用MultipleActiveResultSets复用Sql Server 2008数据库连接
    C# Func<>委托
    你是如何学会正则表达式的?
    Kibana:Windows下安装和运行Kibana
    Elasticsearch(ES)各版本的下载安装与Kibana各版本的下载安装
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13759069.html
Copyright © 2020-2023  润新知