📟作者主页:慢热的陕西人
🌴专栏链接:力扣刷题日记
📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言
牛客热题:反转单向链表
题目链接
题解
方法一:简单反转
思路:
特殊情况:
1.空链表:直接返回头指针
2.一个节点的链表:直接返回头指针
普遍情况(两个或两个以上节点的情况):
1.我们可以用三个指针来实现:
pre:表示最左的节点
cur:表示当前遍历的节点
n: 表示的是当前节点的下一个节点
2.所以我们每一次只需要将当前节点的next指向pre即可,然后再将pre指向cur,cur指向n;
同时n指向自己的next,直到cur指向空指针则完成链表的反转。
代码
ListNode* ReverseList(ListNode* head)
{
//空链表直接返回和一个节点的情况
if(head == nullptr || head->next == nullptr) return head;
ListNode* cur = head;
ListNode* n = cur->next;
ListNode* pre = nullptr;
while(cur != nullptr)
{
cur->next = pre;
pre = cur;
cur = n;
if(n != nullptr)
n = n->next;
}
return pre;
}
复杂度
时间复杂度:O(N) ,遍历一次链表
空间复杂度:O(1) ,只使用了常数量级的变量个数
方法二:递归
思路:
如何想到递归:因为我们反转单向链表的一个难点就是,无法快速的获取当前节点的上一个节点。
所以我们可以利用函数的栈帧来帮我们存储。细节的思路直接体现在代码注释:
代码
ListNode* ReverseList(ListNode* head)
{
//空链表直接返回和一个节点的情况
if(head == nullptr || head->next == nullptr) return head;
//存储head的next
ListNode* n = head->next;
//re表示为最尾部节点,也就是反转后的头节点
//ReverseList(n)就是将n包括n之后的所有节点进行反转
//反转好后再将其的头节点返回
ListNode* re = ReverseList(n);
//那么n就是ReverseList反转好后链表的尾节点
n->next = head;
//这时候其实head和n构成了一个环
//所以我们需要让head的next指向nullptr
head->next = nullptr;
//最后返回反转后链表的头指针
return re;
}
复杂度
时间复杂度:O(N) ,遍历一次链表
空间复杂度:O(1) ,只使用了常数量级的变量个数