BM1 反转链表(C语言)

本文介绍了如何使用C语言在O(1)空间复杂度和O(n)时间复杂度下反转一个长度不超过10000的单链表。通过设立预前节点pre和后继节点next辅助操作,详细讲解了反转链表的思路与步骤,并提供了具体代码实现。

BM1 反转链表(C语言)

描述
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

数据范围: 0\leq n\leq10000≤n≤1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。

如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
在这里插入图片描述

心得:

这道题让我们反转链表,如果直接用脑子想会很混乱,所以设一个变量pre记录运行到的节点的前一个,next记录运行到的节点的后一个,会让问题变得好想一点。
重点是写while中的代码,可以这样记忆:
假设“当前节点->next”为尾,“当前节点”为头
1,next 尾
2, 尾 pre
3,pre 头
4, 头 next;
最后,一定要记得返回pre;

代码:

/***
  struct ListNode {
	int val;
 	struct ListNode *next;
 };
*/

/**
 * 
 * @param pHead ListNode类 
 * @return ListNode类
 */
struct ListNode
### BM1 反转链表问题详解 BM1 是牛客网面试必刷 TOP101 中的一道经典算法题,主要考察链表的操作能力。以下是关于该问题的详细说明和题解。 #### 问题描述 给定一个单向链表的头节点 `pHead`,要求将该链表反转并返回新的头节点。 #### 示例输入输出 - 输入:链表 `1 -> 2 -> 3 -> 4 -> 5` - 输出:链表 `5 -> 4 -> 3 -> 2 -> 1` #### 解题思路 链表反转的核心思想是改变链表中每个节点的指向,使原本的后继节点变为前驱节点。可以通过迭代或递归的方式实现。 #### 方法一:迭代法 迭代法通过逐步遍历链表,调整节点的指向来完成反转操作。具体步骤如下: 1. 初始化三个指针:`pre`(前驱节点)、`cur`(当前节点)和 `temp`(临时存储下一个节点)。 2. 遍历链表,每次将当前节点的 `next` 指向前驱节点,并更新指针位置。 3. 最终返回新的头节点。 代码实现如下: ```cpp class Solution { public: ListNode* ReverseList(ListNode* pHead) { if (pHead == nullptr) return nullptr; // 处理空链表的情况 ListNode* pre = nullptr; // 前驱节点初始化为空 ListNode* cur = pHead; // 当前节点从头节点开始 while (cur != nullptr) { // 遍历链表 ListNode* temp = cur->next; // 保存当前节点的下一个节点 cur->next = pre; // 将当前节点的 next 指向前驱节点 pre = cur; // 更新前驱节点为当前节点 cur = temp; // 更新当前节点为下一个节点 } return pre; // 返回新的头节点 } }; ``` #### 方法二:递归法 递归法通过不断调用自身来反转链表。其核心思想是从最后一个节点开始逐层反转。需要注意的是,递归方法可能会导致栈溢出问题,因此对于大规模链表不推荐使用。 代码实现如下: ```cpp class Solution { public: ListNode* ReverseList(ListNode* pHead) { if (pHead == nullptr || pHead->next == nullptr) { return pHead; // 如果当前节点为空或为尾节点,则直接返回 } ListNode* newHead = ReverseList(pHead->next); // 递归反转后续节点 pHead->next->next = pHead; // 将当前节点的 next 指向自己 pHead->next = nullptr; // 将当前节点的 next 置为空 return newHead; // 返回新的头节点 } }; ``` #### 时间与空间复杂度分析 - **迭代法**: - 时间复杂度:O(n),需要遍历整个链表一次[^1]。 - 空间复杂度:O(1),仅使用了常数级别的额外空间。 - **递归法**: - 时间复杂度:O(n),同样需要遍历整个链表一次[^2]。 - 空间复杂度:O(n),递归调用会占用栈空间,最坏情况下栈深度为 n。 #### 注意事项 1. 链表为空时需特殊处理,避免空指针异常。 2. 在反转过程中,确保不会丢失链表的后续节点。 3. 迭代法通常比递归法更高效且安全。 ### 总结 BM1 反转链表是一道经典的链表操作题目,考察了对链表结构的理解以及基本的算法设计能力。通过上述两种方法可以有效解决该问题,实际应用中推荐使用迭代法以避免递归带来的栈溢出风险。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值