【题目描述】
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
【示例1】
![](https://img-blog.csdnimg.cn/img_convert/2e32db0dc8b135eb56f06e172c145b29.png)
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
【示例2】
![](https://img-blog.csdnimg.cn/img_convert/cd6b768895d605d2159505bce230efa8.png)
输入:head = [1,2]
输出:[2,1]
【示例3】
输入:head = []
输出:[]
【思路】
![](https://img-blog.csdnimg.cn/img_convert/d4bd57a610b1706dec0c212df69ed4bc.gif)
首先定义一个cur指针,指向头节点,再定义一个pre指针,初始化为NULL。
要先使用tmp指针用来保存cur->next节点。为什么要保存这个节点呢?因为下面的操作使cur->next = pre,这里会改变cur->next的节点,不保存的话会找不到下一个需要翻转的位置。
执行循环逻辑,使得cur和pre一直往后走。
那么什么时候结束循环呢?
应该是cur == NULL的时候,这时pre正好为链表的最后一个节点,完成所有节点的翻转。此时我们返回pre指针即可,pre指向翻转后链表的头节点。
【代码】
双指针解法:
C++代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *temp;// 用来保存cur的下一个节点
ListNode *cur = head;
ListNode *pre = nullptr;
while(cur) {
temp = cur->next;
cur->next = pre; // 翻转操作
// 更新pre和cur指针
pre = cur;
cur = temp;
}
return pre;
}
};
递归解法:
递归的写法稍微抽象一些,其实逻辑与双指针算法是一样的,同样是将cur指向pre,当cur为空的时候结束。
初始化的时候,pre为空,cur为头节点。
C++代码如下:
class Solution {
public:
ListNode* reverse(ListNode *pre, ListNode *cur) {
if(cur == nullptr) return pre;
ListNode *temp = cur->next;
cur->next = pre;
return reverse(cur, temp);
}
ListNode* reverseList(ListNode* head) {
return reverse(nullptr, head);
}
};