• 206. Reverse Linked List + 92. Reverse Linked List II


    ▶ 关于单链表翻转的两个问题。

    ▶ 206. 翻转整个单链表。

    ● 自己的代码,9 ms,使用了递归。

     1 class Solution
     2 {
     3 public:
     4     ListNode* reverseList(ListNode* head)
     5     {
     6         if (head == nullptr)
     7             return nullptr;
     8         ListNode *p;
     9         for (p = head; p->next != nullptr; p = p->next);// 找到末元(翻转后的首元)
    10         reverseNode(head);
    11         return p;        
    12     }
    13     inline void reverseNode(ListNode* p)// 翻转以 p 指向的结点为首元的单链表,并返回一个指向末元的指针(方便下一次挂上新的首元)
    14     {        
    15         if (p == nullptr || p->next == nullptr)
    16             return;
    17         reverseNode(p->next);           // 翻转除首元意外的部分
    18         p->next->next = p;              // 把首元挂到最后
    19         p->next->next->next = nullptr;  // 去掉成环的部分
    20         return ;
    21     }
    22 };

    ● 大佬的代码,9 ms,逐格移动。

     1 class Solution
     2 {
     3 public:
     4     ListNode* reverseList(ListNode* head)
     5     {
     6         if (head == NULL || head->next == NULL)
     7             return head;
     8         ListNode *prev, *cur, *temp;
     9         for(prev = NULL, cur = head; cur != NULL;)
    10         {
    11             temp = cur->next;
    12             cur->next = prev;
    13             prev = cur;
    14             cur = temp;
    15         }
    16         return prev;
    17     }
    18 };

    ▶ 92. 要求翻转单链表中第 m 到第 n(两端包含,且 m 可以等于 n)之间的所有元。

    ● 自己的代码,4 ms,使用了第 206 题的结果。

     1 class Solution
     2 {
     3 public:
     4     ListNode* reverseBetween(ListNode* head, int m, int n)
     5     {
     6         if (head == nullptr)
     7             return head;
     8         ListNode newHead(-999), *lp, *rp, *lpprev, *temp;
     9         newHead.next = head;
    10         int i, j;
    11         for (i = 1, lpprev = &newHead; i < m && lpprev != nullptr; i++, lpprev = lpprev->next);// 找到第 m-1 元和第 m 元
    12         if (lpprev == nullptr || (lp = lpprev->next) == nullptr)
    13             return head;
    14         for (j = i, rp = lp; j < n && rp != nullptr; j++, rp = rp->next);// 找到第 n 元
    15         if (rp == nullptr)
    16             return head;
    17         temp = rp->next;               // 尾部不翻转部分的首元
    18         rp->next = nullptr;            // 断开翻转部分的尾部链接
    19         lpprev->next = reverseList(lp);// 调用翻转函数
    20         lp->next = temp;               // 重新接上尾部
    21         return newHead.next;
    22     }
    23     ListNode* reverseList(ListNode* head)
    24     {
    25         if (head == nullptr)
    26             return nullptr;
    27         ListNode *p;
    28         for (p = head; p->next != nullptr; p = p->next);// 找到末元(翻转后的首元)
    29         reverseNode(head);
    30         return p;
    31     }
    32     inline void reverseNode(ListNode* p)// 翻转以 p 指向的结点为首元的单链表
    33     {
    34         if (p == nullptr || p->next == nullptr)
    35             return;
    36         reverseNode(p->next);           // 翻转除首元意外的部分
    37         p->next->next = p;              // 把首元挂到最后
    38         p->next->next->next = nullptr;  // 去掉成环的部分
    39         return;
    40     }
    41 };

    ● 大佬的代码,4 ms,也是使用逐格移动。

     1 class Solution
     2 {
     3 public:
     4     ListNode* reverseBetween(ListNode* head, int m, int n)
     5     {
     6         ListNode *first = new ListNode(0), *t_head, *first_reverse, *node;
     7         first->next = head;
     8         t_head = first;
     9         for (int i = 0; i<m - 1; t_head = t_head->next, i++)
    10             first_reverse = t_head->next;
    11         node = t_head->next;
    12         for (int i = m; i <= n; i++)
    13         {
    14             ListNode * temp = node->next;
    15             node->next = t_head->next;
    16             t_head->next = node;
    17             node = temp;
    18         }
    19         first_reverse->next = node;
    20         return first->next;
    21     }
    22 };

    ▶ 一个副产品,交换单链表中的两个元素。我已开始把第 92 题理解错了,以为只是交换单链表中第 m 和第 n 个元素,所以写成了下面的东西。

     1 class Solution
     2 {
     3 public:
     4     ListNode* reverseBetween(ListNode* head, int m, int n)
     5     {
     6         if (head == nullptr)
     7             return head;
     8         ListNode newHead(-999), *lp, *rp, *lpprev, *rpprev, *temp;
     9         newHead.next = head;
    10         int i, j;
    11         for (i = 1, lpprev = &newHead; i < m && lpprev != nullptr; i++, lpprev = lpprev->next);
    12         if (lpprev == nullptr || (lp = lpprev->next) == nullptr)
    13             return head;
    14         for (j = i, rpprev = lpprev; j < n && rpprev != nullptr; j++, rpprev = rpprev->next);
    15         if (rpprev == nullptr || (rp = rpprev->next) == nullptr)
    16             return head;
    17         lpprev->next = rp;
    18         rpprev->next = lp;
    19         swap(lp->next, rp->next); 
    20         return newHead.next;
    21     }
    22 };
  • 相关阅读:
    隔离模式-常用的架构设计原则
    代理模式-常用的架构设计原则
    重试模式-常用的架构设计原则
    断路器模式-常用的架构设计原则
    磁盘IOPS(每秒读写次数)的计算方法与测量
    Spring深入浅出(七),自动装配,byName/byType
    Spring深入浅出(六),依赖注入,注入集合(含注入 Bean 引用)
    Spring深入浅出(五),依赖注入,构造函数/设值/注入内部Bean
    Spring深入浅出(四),Spring Bean定义继承
    【算法】算法的艺术(四)
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/8323701.html
Copyright © 2020-2023  润新知