【问题】输入一个链表,反转链表后,输出新链表的表头。

【思路】第一种思路,使用一个堆栈去保存所有的节点,然后再进行依次弹出后并连接起来即可!

 1/*
 2struct ListNode {
 3    int val;
 4    struct ListNode *next;
 5    ListNode(int x) :
 6            val(x), next(NULL) {
 7    }
 8};*/
 9class Solution {
10public:
11    ListNode* ReverseList(ListNode* pHead) {
12        stack<ListNode*> sta;
13        ListNode* cur = pHead;
14        ListNode* newHead;     // 要返回的头结点
15        if(pHead == nullptr || pHead->next == nullptr){
16            return pHead;
17        }
18        while(cur->next != nullptr){
19            sta.push(cur);
20            cur = cur->next;
21        }
22        newHead = cur;    // 最后一个节点为新链表的头结点
23        while(!sta.empty()){
24            cur->next = sta.top();
25            sta.pop();
26            cur = cur->next;
27        }
28        cur->next = nullptr;
29        return newHead;
30    }
31};

第二种,如果不使用额外的空间的话,我们可以使用两个指针pre和next, 对链表相邻的两个节点进行交换调整,这才是面试官想要看到的算法!循环中主要有四步:

  1. 保存当前节点的next节点,下一步要改变,需要保存

  2. 修改当前节点的next节点为pre(前驱节点)

  3. pre指针直到当前节点

  4. pHead指针指向next节点(向后移动)

  5. 1/*
     2struct ListNode {
     3    int val;
     4    struct ListNode *next;
     5    ListNode(int x) :
     6            val(x), next(NULL) {
     7    }
     8};*/
     9class Solution {
    10public:
    11    ListNode* ReverseList(ListNode* pHead) {
    12        if(pHead == nullptr || pHead->next == nullptr){
    13            return pHead;
    14        }
    15        ListNode* pre = nullptr;
    16        ListNode* next = nullptr;
    17        while(pHead != nullptr){
    18            next = pHead->next;  // 保存next节点,因为下一步要修改pHead.next
    19            pHead->next = pre;   // 第一次pre=null,即第一个节点指向空
    20            pre = pHead;
    21            pHead = next;
    22        }
    23        return pre;
    24    }
    25};