leetcode:206. 反转链表
题目
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:![[简单] 206. 反转链表 - 图1](/uploads/projects/liangduo-rjrcs@ggu4wq/cd9849e2a16c3d908b8652e97d9a7a25.jpeg)
输入:head = [1,2,3,4,5]输出:[5,4,3,2,1]
示例 2:![[简单] 206. 反转链表 - 图2](/uploads/projects/liangduo-rjrcs@ggu4wq/8eecc1cb2f421d760aa20574f269b32b.jpeg)
输入:head = [1,2]输出:[2,1]
示例 3:
输入:head = []输出:[]
解答 & 代码
解法一:迭代法
/*** 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* pre = nullptr; // 前一个节点ListNode* cur = head; // 当前节点// 遍历链表,反转while(cur != nullptr){ListNode* next = cur->next; // 记录下一个节点cur->next = pre; // 将当前节点的 next 指向前一个节点pre = cur; // 前一个节点 pre 右移cur = next; // 当前节点 cur 右移}return pre; // 返回反转后的头节点}};
复杂度分析:设链表节点数为 N
- 时间复杂度 O(N)
- 空间复杂度 O(1)
执行结果:
执行结果:通过执行用时:4 ms, 在所有 C++ 提交中击败了 94.42% 的用户内存消耗:8 MB, 在所有 C++ 提交中击败了 90.84% 的用户
解法二:递归
递归链表和递归二叉树其实本质是一样的,以递归处理 next 节点这一语句为分界线,
- 之前的位置是正序位置(进入当前节点),可用于正序输出链表节点;
- 之后的位置是逆序位置(离开当前节点),可用于逆序输出链表节点。
本题的递归解法类似于动态规划的思想,将当前的大问题分解为子问题。
- 递归函数定义:输入一个节点
head,将以head为头节点的链表反转,并返回反转后的头节点 - 分解为子问题:递归将以
head->next为头节点的链表反转,并返回反转后的头节点,即为last - 将当前节点接到
last链表的尾部,就完成了对以head为头节点的链表反转- 如何定位到
last链表的最后一个节点:head->next是last链表反转前的头节点,也就是反转后的尾节点,因此,令head->next->next = head即可将head节点拼接到尾部
- 如何定位到
- 当然,由于当前节点
head是反转后的最后一个节点,因此需要将head->next设为nullptr 返回反转后链表的头节点
last/*** 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:// 递归函数定义:输入一个节点 head,将以 head 为头节点的链表反转,并返回反转后的头节点ListNode* reverseList(ListNode* head) {// 递归结束条件if(head == nullptr || head->next == nullptr)return head;// 递归将以 head->next 为头节点的链表反转,并返回反转后的头节点,记为 lastListNode* last = reverseList(head->next);// 将当前节点 head 接到 last 链表的尾部head->next->next = head;// 当前节点 head 是反转后的最后一个节点,因此需要将 head->next 设为 nullptrhead->next = nullptr;// 返回 head 链表反转后的头节点return last;}};
复杂度分析:设链表节点数为 N
时间复杂度 O(N)
- 空间复杂度 O(N):递归栈空间复杂度
执行结果:
执行结果:通过执行用时:4 ms, 在所有 C++ 提交中击败了 94.42% 的用户内存消耗:8.2 MB, 在所有 C++ 提交中击败了 22.11% 的用户
