原题链接https://www.acwing.com/problem/content/description/33/
参考链接:https://www.acwing.com/solution/content/6583/ (有动画)
y总:https://www.acwing.com/solution/content/743/
迭代
一个pre指针,保留前继节点,一个cur,指向当前节点,一个next,指向下一个节点。
每次:
next保存cur的下一个节点
cur的next指向pre
向后移动一位:pre移到cur,cur移动next
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 记录前驱节点
ListNode* pre = nullptr;
auto cur = head;
while(cur)
{
// 存一下下一个节点
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
// while结束的时候,cur为NULL,pre正好是头节点
return pre;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL) return NULL;
if(head->next == NULL) return head;
ListNode* p = head;
// 先找到最后一个节点
while(p->next->next != NULL)
{
p = p->next;
}
// 新建一个
ListNode* new_head = p->next;
p->next = NULL;
ListNode* p2 = new_head;
while(1)
{
p = head;
if(p->next == NULL)
{
p2->next = p;
break;
}
while(p->next->next)
{
p = p->next;
}
p2->next = p->next;
p->next = NULL;
p2 = p2->next;
}
return new_head;
}
};
递归:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
/*
递归版本:
首先我们先考虑 reverseList 函数能做什么,
它可以翻转一个链表,并返回新链表的头节点,
也就是原链表的尾节点。
所以我们可以先递归处理 reverseList(head->next),这样我
们可以将以head->next为头节点的链表翻转,并得到原链表的
尾节点tail,此时head->next是新链表的尾节点,我们令它的
next指针指向head,并将head->next指向空即可将整个链表翻转
,且新链表的头节点是tail。
*/
if(!head || !head->next) return head;
// 处理head->next
ListNode* tail = reverseList(head->next);
// 把head添加到最后,同时把head->next置为空
// 上面的递归函数执行完以后,head->next是新链表的尾节点
// 我们让新链表的尾节点的next为原来的列表的头节点,完成反转
head->next->next = head;
// head->next置空
head->next = nullptr;
return tail;
}
};