爨爨爨好

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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

▶ 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 };

 

posted on 2018-01-21 11:14  爨爨爨好  阅读(160)  评论(0编辑  收藏  举报