系列专栏
《分治》
《模拟》
《Linux》
目录
1、题目链接
2、题目介绍
3、解法(快慢指针)
解题步骤:
关键点:
复杂度分析:
4、代码
1、题目链接
206. 反转链表 - 力扣(LeetCode)
2、题目介绍
3、解法(快慢指针)
这里采用的就是三个指针(或者可以说是两个指针加一个临时变量)的方法来实现链表的反转。
解题步骤:
- 边界条件处理:
- 首先检查输入的头节点
head
是否为nullptr
。如果是,直接返回nullptr
,因为空链表反转后仍然是空链表。- 初始化指针:
cur
指针初始化为nullptr
,它将会指向反转后的链表的当前节点。在反转过程中,cur
会逐渐成为反转后链表的头节点。NEXT
指针初始化为head
,它指向当前正在处理的节点。tmp
指针用于临时存储NEXT->next
的值,以便在反转NEXT
节点的指向后,能够继续遍历原链表。- 迭代反转链表:
- 使用一个
while
循环,条件是NEXT
不为nullptr
,表示还有节点需要处理。- 在每次循环中,首先用
tmp
保存NEXT->next
的值,即当前节点的下一个节点。- 然后将
NEXT->next
指向cur
,完成当前节点的反转。- 更新
cur
和NEXT
的值,cur
指向NEXT
(现在已反转),NEXT
指向tmp
(即原来的下一个节点)。- 返回结果:
- 当
NEXT
为nullptr
时,循环结束,此时cur
指向反转后的链表的头节点。- 返回
cur
即可。关键点:
- 指针的更新顺序:先改变当前节点的
next
指向,再移动指针。- 防止链表断裂:使用
tmp
临时变量保存未处理的链表部分,确保在反转当前节点后,仍然可以访问到剩余链表。- 理解指针的作用:
cur
是反转后链表的当前节点,NEXT
是当前正在处理的节点,tmp
是临时存储的下一个节点。复杂度分析:
- 时间复杂度:O(n),其中n是链表的长度。因为需要遍历整个链表。
- 空间复杂度:O(1)。只使用了常数个额外变量,没有使用与链表长度相关的额外空间。
4、代码
/**
* 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* cur = NULL, *NEXT = head;
while (NEXT != NULL)
{
ListNode* tmp = NEXT->next;//tmp临时指针,存放未被反转的链表,防止丢失
NEXT->next = cur;
cur = NEXT;
NEXT = tmp;
}
return cur;
}
};