微软面试题: LeetCode 206. 反转链表 出现次数:3

  翻转单链表是出现在 各大公司 的面试中频率最高的一题了!!!

有 头插法 和 递归法 两种实现方法,一次性写出 bug free 的代码不是件容易的事!

具体看下面的代码和注释 如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11 //头插法
12     ListNode* reverseList(ListNode* head) {
13         
14         if(head == NULL || head->next == NULL)  return head;
15         //1. 新建一个只含有一个dummy节点的链表,dummy节点成为哨兵节点;
16         //2. 遍历原链表,并将原链表的节点依次摘下,从表头插入到dummy节点的链表中;
17         //   从原链表摘下节点插入前保存指向下一个节点的指针,dummy链表中要维护一个始终指向头节点的指针;
18         //3. 原链表的节点都插入到dummy节点后,删除dummy节点释放内存,并将此时的最后一个节点 head->next = NULL;
19         ListNode* dummy = new ListNode();
20         //q 始终指向dummy链表头节点
21         ListNode* q = dummy;
22         //p 是遍历并摘除原链表的工作指针
23         ListNode* p = head;
24         while(p)
25         {
26             //指向原链表待摘除节点的下一节点,避免遍历的过程中发生断链
27             ListNode* tmptr = p->next;
28             //将从原链表摘下的节点插入dummy链表头部
29             p->next = q;
30             //q 重新指向dummy链表头节点
31             q = p;
32             //p 指向原链表中的下一个待摘除节点
33             p = tmptr;
34         }
35         //释放哨兵节点内存
36         delete dummy;
37         //head 是翻转后链表的最后一个节点
38         head->next = NULL;
39         // q 是翻转后链表的头节点
40         return q;
41     }
42 //递归法
43     ListNode* reverseList(ListNode* head)
44     {
45         //递归跳出条件:当前链表(子链表)为空或只有一个节点,直接返回head,不需再翻转。
46         if(head == NULL || head->next == NULL)
47         {
48             return head;
49         }
50         //指向 reverseList(head->next) 的最后一个节点的指针
51         ListNode* tmp = head->next;
52         //翻转 head->next
53         ListNode* res = reverseList(head->next);
54         //在reverseList(head->next)后面链接上head
55         tmp->next = head;
56         //head->next 置 NULL
57         head->next = NULL;
58         return res;
59     }
60 };

 

上一篇:[LeetCode] 206. Reverse Linked List


下一篇:PHP 页面静态化/纯静态化/伪静态化