力扣206. 反转链表
题目来源(力扣):
https://leetcode.cn/problems/reverse-linked-list/description/
题目描述:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
基本思路:
利用pre指向上一个节点,p指向当前节点,nex指向下一个节点。
具体而言,每次循环先保存nex=p->next,然后更改p->next为pre。这样就完成了一次链表的反转。
之后再修改pre=p; p=nex; 为下一次循环做准备
边界为p==nullptr,即完成了所有链表节点的反转,且此时pre来到了原链表的末尾(因此反转后的链表头结点正好是pre)
所以就是
while(p!=nullptr){
nex=p->next;
p->next=pre;
pre=p;
p=nex;
}
另外,该迭代写法可以改成递归写法,实际上的逻辑是一样的~
参考《代码随想录》如下:
代码实现-迭代(好理解):
class Solution
{
public:
ListNode *reverseList(ListNode *head)
{
ListNode *pre = nullptr, *p = head, *nex;
while (p)
{
nex = p->next;
p->next = pre;
pre = p;
p = nex;
}
return pre;
}
};
代码实现-递归:
class Solution
{
public:
ListNode *reverse(ListNode *pre, ListNode *p)
{
if (p == nullptr)
return pre;
// 每层递归做2件事:记录nex、更改当前p的指向为pre
ListNode *nex = p->next;//1.
p->next = pre; //2.
return reverse(p, nex); // 这句的逻辑和迭代法完全相同,等价于 pre=p,p=nex; 相当于为下一次操作做准备
}
ListNode *reverseList(ListNode *head)
{
ListNode *pre = nullptr, *p = head;
return reverse(pre, p);
}
};
补充
LinkNode定义为:
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) {}
};
算法时间复杂度为 O(n)
浙公网安备 33010602011771号