leetcode链接:206. 反转链表
题目描述:
给你单链表的头节点 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.如果是空则直接返回
2.如果只有一个也直接返回
3.大于等于2个元素则进行反转
1)可以new一个链表来倒着存值
2)在原链表上进行操作
实现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) {
if(head == nullptr)
{
return head;
}
else
{
ListNode* cur = head;
ListNode* prev = nullptr;
while(cur)
{
ListNode* nextnode = cur->next;
cur->next = prev;
prev = cur;
cur = nextnode;
}
return prev;
}
}
};
实现2:在原链表上操作
/**
* 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) {
if (head == nullptr) {
return head;
}
ListNode* prev = nullptr; // 先初始化为 nullptr
ListNode* cur = head;
while (cur != nullptr) {
ListNode* front = cur->next; // 保存下一个节点
cur->next = prev; // 反转当前节点的指向
prev = cur; // 移动 prev
cur = front; // 移动到下一个节点
}
return prev; // prev 现在是新的头节点
}
};
需要注意的是,这里有个常见错误,下面我在写这道题的时候就已经犯了,不能在循环外先定义front,这是因为会存在一种情况只有一个结点,这时我这种写法就已经错了造成空指针问题了。、
实现3:递归
这里引用一篇题解的动图来说明递归的实现过程下面是原文链接
这里举一个官方题解下的评论来具体来说明一下调用过程:
第一轮出栈,head为5,head.next为空,返回5
第二轮出栈,head为4,head.next为5,执行head.next.next=head也就是5.next=4,
把当前节点的子节点的子节点指向当前节点
此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开4.next=null
此时链表为1->2->3->4<-5
返回节点5
第三轮出栈,head为3,head.next为4,执行head.next.next=head也就是4.next=3,
此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开3.next=null
此时链表为1->2->3<-4<-5
返回节点5
第四轮出栈,head为2,head.next为3,执行head.next.next=head也就是3.next=2,
此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开2.next=null
此时链表为1->2<-3<-4<-5
返回节点5
第五轮出栈,head为1,head.next为2,执行head.next.next=head也就是2.next=1,
此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开1.next=null
此时链表为1<-2<-3<-4<-5
返回节点5
出栈完成,最终头节点5->4->3->2->1