跳转至

206. 反转链表

原题链接

题目描述

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

1
2
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

1
2
输入:head = [1,2]
输出:[2,1]

示例 3:

1
2
输入:head = []
输出:[]

提示:

  • 链表中节点的数目范围是 \([0, 5000]\)
  • \(-5000\) \(≤\) \(Node.val\) \(≤\) \(5000\)

进阶: 链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?


遍历

时间复杂度\(O(n)\)  空间复杂度\(O(1)\)

定义前驱结点为pre,当前结点为cur,由于每次反转需要把当前结点的next指针指向前驱结点pre,所以需要再定义一个next用来存储当前结点的下一个结点。

反转操作:

  1. 把当前结点的next指针指向前驱结点
  2. 把前驱结点pre移到当前结点cur上;
  3. 把当前结点cur移到之前定义的next结点处。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* cur = head;
        while (cur) {
            ListNode* next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
};

递归

时间复杂度\(O(n)\)  空间复杂度\(O(n)\)

定义tail结点为reverseList(head)函数的返回值。当没有next结点时,返回head结点。

否则,将当前结点的next结点的next指向当前head结点,head->next置为空指针nullptr

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head || !head->next) return head;

        ListNode* tail = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;

        return tail;
    }
};
回到页面顶部