原题链接: 206. 反转链表 - 力扣(Leetcode)
tag: 链表.
一. 题目
给你单链表的头节点 head , 请你反转链表, 并返回反转后的链表.
二. 题解
本题采用三指针的解法, 前指针 prev , 中指针 curr , 后指针 temp .
反转前.
ListNode* prev = nullptr, * curr = head;
开始进行反转操作.
定义一个 temp 指针指向 curr 节点的后继节点.
ListNode* temp = curr->next;
为什么要保存 curr 节点的后继节点呢? 因为接下来会进行反转操作, 也就是改变 curr->next 的指向, 将 curr->next 指向 prev 节点, 如果不用 temp 指针保存 curr 节点的后继节点, 就再也找不到 curr 节点原来的后继节点了, 无法继续对链表进行反转操作, 所以我们需要用 temp 指针保存 curr 节点的后继节点.
进行反转操作(改变 curr->next 的指向).
curr->next = prev;
更新 prev 指针.
prev = curr;
更新 curr 指针.
curr = temp;
继续反转链表.
定义一个 temp 指针指向 curr 节点的后继节点.
ListNode* temp = curr->next;
进行反转操作(改变 curr->next 的指向).
curr->next = prev;
更新 prev 指针.
prev = curr;
更新 curr 指针.
curr = temp;
curr == nullptr, 遍历链表完毕, 循环终止, 此时 prev 正好指向反转后链表的头节点.
反转后.
三. 复杂度分析
时间复杂度: O(N), N 是链表的长度, 完成链表的反转需要遍历链表一次.
空间复杂度: O(1).
四. 代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr, * curr = head; // 定义前指针 prev, 中指针 curr
while (curr != nullptr) {
ListNode* temp = curr->next; // 保存 curr 的后继节点
curr->next = prev; // 进行反转操作
prev = curr; // 更新 prev 指针
curr = temp; // 更新 curr 指针
}
return prev; // 返回新的头节点
}
};