剑指 Offer 24. 反转链表

剑指 Offer 24. 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

  • 方法:
  1. 三个指针。

pre指针指向当前操作节点的前一个,cur指针指向当前操作节点,next指针指向当前操作节点的后一个。

遍历链表,让next指针指向cur,cur指向pre,三个指针依次后移。

特例情况:

  • 链表中没有节点,返回nullptr
  • 链表中只有一个节点,返回head
  • 链表中只有两个节点,修改指向后返回
ListNode* reverseList(ListNode* head) {
if(head == nullptr) return nullptr;
if(head->next == nullptr) return head;
if(head->next->next == nullptr) {
ListNode* res = head->next;
head->next->next = head;
head->next = nullptr;
return res;
}
ListNode* pre = head;
ListNode* cur = head->next;
ListNode* next = head->next->next;
pre->next = nullptr;
while(next != nullptr) {
ListNode* temp = next->next;
next->next = cur;
cur->next = pre;
pre = cur;
cur = next;
next = temp;
}
return cur;
}
  • 时间复杂度:O(n)遍历链表
  • 空间复杂度:O(1)
  1. 迭代(双指针)
    定义两个指针,cur指针指向链表head, pre指针指向nullptr
    遍历链表,定义临时节点tmp指向cur的next节点,改变cur的指向指向pre节点
    移动pre节点指向cur, cur指向tmp
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* pre = nullptr;
while(cur != nullptr) {
ListNode* tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
  • 时间复杂度:O(n), 需要遍历一次链表
  • 空间复杂度: O(1)
  1. 递归
    递归遍历链表,当递归到尾节点时终止递归,在回溯过程中改变cur指针指向前一个节点pre
    递归结束条件:cur == nullptr,返回尾节点pre
    递归过程:
  • 递归后继节点,记录返回值(反转后的头结点)
  • 修改cur节点指向
ListNode* dfs(ListNode* cur, ListNode* pre) {
if(cur == nullptr) return pre;
ListNode* tmp = dfs(cur->next, cur);
cur->next = pre;
return tmp;
}
ListNode* reverseList(ListNode* head) {
ListNode* res = dfs(head, nullptr);
return res;
}
  • 时间复杂度:O(n), 遍历链表
  • 空间复杂度:O(n), n为递归深度

posted on   SocialistYouth  阅读(10)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人

统计

点击右上角即可分享
微信分享提示