1.题目
输入一个链表,反转链表后,输出新链表的表头。
2.我的题解
反转操作,最容易想到的就是使用栈,先一个一个入栈,再依次出栈,即可实现反转。
注意:
- 先判断是否为空
- 最后一个节点要指向
NULL
,否则造成链表死循环。 - 该方法耗费额外空间
O(n)
。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL)return NULL;
ListNode * res = pHead;
stack<ListNode *> s;
while(res){
s.push(res);
res=res->next;
}
pHead=s.top();
s.pop();
res=pHead;
while(!s.empty()){
res->next=s.top();
res=res->next;
s.pop();
}
res->next=NULL;//没有这句会死循环
return pHead;
}
};
3.别人的题解
3.1 三指针法
使用pre,cur,next
三个指针,既能反转当前节点,又不会丢失后续链表。
步骤 | 状态 |
---|---|
0 | |
1 | |
… | … |
last |
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if (pHead == NULL || pHead->next == NULL)return pHead;
ListNode * pre = NULL, *cur = pHead, *next = cur->next;
while (cur) {
cur->next = pre;
pre = cur;
cur = next;
if(next)next = next->next;
}
return pre;
}
};
这里注意,结束时next
指针已经偏移出两个单位了,但其实最多偏移一个单位(即NULL
),之后再想向后偏移就会报错,所以要加一个判断:if(next)next = next->next;
。
另一种解决方法:开始时令next=cur
,在循环里第一步让next=cur->next
。
ListNode* ReverseList(ListNode* pHead) {
if (pHead == NULL || pHead->next == NULL)return pHead;
ListNode * pre = NULL, *cur = pHead, *next = cur;
while (cur) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
3.2 递归法
有这个想法但一时间没有想透彻。最后百度了才搞懂。参考1 ,贴一波图1。
步骤 | 状态 |
---|---|
输入输出 | |
递归表示 | |
解决子问题 | |
递归后的操作 |
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL || pHead->next==NULL)return pHead;
ListNode * tmp = ReverseList(pHead->next);
pHead->next->next = pHead;
pHead->next=NULL;
return tmp;
}
};
3.3 头插法
使用辅助节点,遇到一个节点就使用头插操作,最后返回辅助节点的下一个节点。
每次循环需要记录的是原链表的下一个节点。
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode * head = new ListNode(0);
ListNode *next=pHead;
while(pHead){
next=pHead->next;
pHead->next = head->next;
head->next=pHead;
pHead=next;
}
return head->next;
}
};
4.总结与反思
(1)简单的链表,多样的解法。