题目链接:
题目:
给你单链表的头节点 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
理解分享:
我采用了迭代的方式来实现链表的反转。
首先,我们检查输入的头节点是否为空,如果为空则直接返回,因为空链表无需反转。
然后,我们定义了三个指针 a
、b
和 c
,它们分别代表当前节点的前一个节点、当前节点和当前节点的后一个节点。
接着,我们进入一个循环,条件是 b
不为空。在循环的每一次迭代中,我们将当前节点 b
的 next
指针指向其前一个节点 a
,然后更新 a
指针为当前节点 b
,b
指针为下一个节点 c
,最后将 c
指针更新为下一个节点。这样做的效果是,不断地将当前节点指向其前一个节点,从而实现了链表的反转。
最后,当 b
为空时,说明已经遍历完整个链表,此时 a
指向的节点即为反转后链表的头节点,因此返回 a
指针即可。
这种方法的时间复杂度是 O(n),其中 n 是链表的长度。
代码:
typedef struct ListNode ll;
// 反转单链表
struct ListNode* reverseList(struct ListNode* head) {
// 如果头节点为空,直接返回
if (!head) {
return head;
}
// 初始化三个指针,a 指向当前节点的前一个节点,b 指向当前节点,c 指向当前节点的下一个节点
ll* a = NULL; // 前一个节点
ll* b = head; // 当前节点
ll* c = b->next; // 下一个节点
// 循环遍历链表节点
while (b) {
// 反转当前节点的 next 指针,使其指向前一个节点
b->next = a;
// 更新指针位置:a 指向当前节点,b 指向下一个节点,c 指向下一个节点的下一个节点
a = b;
b = c;
if (c) {
c = c->next;
}
}
// 返回反转后的链表头节点
return a;
}