题目要求
题解
头插法
简单讲就是从第二个元素起依次插到链表的头部。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head||!head->next) return head;
ListNode dummy(-1);
dummy.next=head;
ListNode *pre=head,*cur=head->next;
while(cur){
pre->next=cur->next;
cur->next=dummy.next;
dummy.next=cur;
cur=pre->next;
}
return dummy.next;
}
};
全程pre指向头结点,其之后的节点为该轮要进行头插的节点。
以下
https://leetcode-cn.com/problems/reverse-linked-list/solution/c-die-dai-fa-di-gui-fa-by-eric-345/
迭代法
和头插法大同小异,看上去更简单。
ListNode* reverseList(ListNode* head) {
if (head == nullptr || head->next == nullptr)
return head;
ListNode* prev = nullptr;
ListNode* cur = head;
while (cur)
{
ListNode* tmp = cur->next; //保存下轮要前插的节点
cur->next = prev; //将cur节点插到新链表的头结点前
prev = cur;//这时头结点变为本轮前移的节点
cur = tmp;//之前保存的节点变为当前节点
}
return prev;
}
迭代法
画图从后向前分析吧。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head||!head->next) return head;
ListNode *p=reverseList(head->next);
head->next->next=head;
head->next=nullptr;
return p;
}
};
附以下playgroud单句调试,方便理解递归的细节,容许我懒一下,就不一句一句分析了。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(!head||!head->next) return head;
ListNode *p=reverseList(head->next);
string out = listNodeToString(head);
cout <<"@1 "<<"head "<< out << endl;
out = listNodeToString(p);
cout <<"p "<< out << endl;
head->next->next=head;
//out = listNodeToString(head);
//cout <<"@2 "<<"head "<< out << endl;
head->next=nullptr;
out = listNodeToString(head);
cout <<"@3 "<<"head "<< out << endl;
out = listNodeToString(p);
cout <<"p "<< out << endl;
return p;
}
@1 head [4, 5]
p [5]
@3 head [4]
p [5, 4]
@1 head [3, 4]
p [5, 4]
@3 head [3]
p [5, 4, 3]
@1 head [2, 3]
p [5, 4, 3]
@3 head [2]
p [5, 4, 3, 2]
@1 head [1, 2]
p [5, 4, 3, 2]
@3 head [1]
p [5, 4, 3, 2, 1]
[5, 4, 3, 2, 1]