“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”
一、题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
提示:
- 链表中节点的数目范围是
[0, 5000] -5000 <= Node.val <= 5000
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
二、思路分析
题意要求我们用迭代或递归方式完成反转,那么我们就来看看如何达到这个要求。
以示例1举例子:head = [1,2,3,4,5]
先来看看迭代的思路:
要让 1->2 这节链表实现反转,变成 2->1 ,肯定是先获取到 2 这个节点,然后将 next 指针指向 1 ,然而这里有一个问题:当我们获取到 2 节点后,已经不能获取 1 节点了,因此我们需要想办法获取 1 节点(怎么搞的,要我获取 2 节点的是你,现在要获取 1 节点的也是你,到底想怎么样)。哈哈,其实很容易解决,我们可以先定义一个全局变量 ans ,在处于 1 节点的时候,将其保存下来,那么当 2 节点需要修改 next 指向为 1 时,指向 ans 就好啦。解决这个之后,事情就好办了,按照这个流程一直下去,知道 head 为 nullptr 即可完成反转了。
注意:反转前的
head最后是指向nullptr的,因此反转链表之后,最后的指针也要指向nullptr,因此一开始的ans变量自然而然要赋值为nullptr,并且遍历到链表的第一个节点时顺便修改其next指向为ans。
再来看看递归的思路:
这里换一种思路,先给出答案,再讲解为什么是这个答案
ListNode* reverseList(ListNode* head) {
if (head == nullptr || head -> next == nullptr) return head;
ListNode* cur = reverseList(head -> next);
head -> next -> next = head;
head -> next = nullptr;
return cur;
}
同样以 head=[1, 2, 3, 4, 5] 为例,链表进入递归函数 reverseList 之后,head 会一直遍历下去,直到链表末尾也就是值为 5 ,发现满足条件 head -> next == nullptr ,于是被 return ,结果 head 变回 4 了,这时候就需要开始进行反转了(终于可以执行第二行之后的代码了呀,真是不容易),仔细看看 head -> next -> next = head 这行代码,我将其拆开来:head(也就是4)-> next == 5、5 -> next(修改5的next指针)== head(4),这样一来原本 4->5 的指向关系就变更为 5->4 了;然后是 head -> next == nullptr ,4 的 next 被指向 nullptr ,其实这里指向哪里无所谓,反正待会还是会被第三行代码修改指向,只是最后整个链表要指向 nullptr ,因此这里就写成指向 nullptr 。
注意:递归做法不要陷进循环里,搞清楚一个递归过程就可以了,其他递归也是一样的过程啊。
三、AC 代码
链表定义如下:
/**
* 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* ans = nullptr;
while (head) {
head -> next = ans;
ans = head;
head = head -> next;
}
return ans;
}
};
方法二:递归法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == nullptr || head -> next == nullptr) return head;
ListNode* cur = reverseList(head -> next);
head -> next -> next = head;
head -> next = nullptr;
return cur;
}
};