题目:
输入一个链表,反转链表后,输出新链表的表头。
思路:
方法1:利用辅助空间,不推荐
利用栈的辅助空间,先将链表元素入栈,再将元素出栈; 利用数组的辅助空间,先遍历链表将其放入一个数组,然后把数组从后往前形成新链表。
方法2:
不需要辅助空间,每一次反转需要维护三个指针,当前节点pNode,前一节点pPre(因为当前节点反转要指向前一节点),下一节点pNext(在改变当前节点指向之前,必须先保存下一节点,否则链表会断开),依次反转,直到遍历完(pNode=NULL,全部节点完成反转)。要注意几点:
1)第一个节点反转之后变为尾节点,应该指向NULL,因此pPre初始化为NULL;
2)最后返回的头指针是最后一个节点,因此当循环结束,pNode=NULL,pPre指向的是最后一个节点,记得要把pPre设为新的链表头结点;
3)特殊情况的处理:空链表,只有一个节点的链表,这种情况直接返回头指针。
方法3:用递归的方法实现
以1->2->3->4为例,先利用递归走到链表末端,首先1节点传入头指针参数,进入else语句,一直递归到最后一个4节点,p->next为空,进入if语句返回4作为newHead;然后pHead变为节点3,上一级返回之后的操作是将当前结点的下下节点指向当前节点(即4指向3),然后将当前节点指向空,这样剩下就是处理1->2->3新链表,可以递归操作。
代码:
参考下面的在线测试代码
在线测试OJ:
AC代码:
非递归
/*
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* pNode = pHead;//当前节点
ListNode* pNext;//下一节点
ListNode* pPre=NULL;//前一节点
ListNode* pNewHead;//新的链表头结点
while(pNode)
{
pNext = pNode->next;
pNode->next = pPre;
pPre = pNode;
pNode = pNext;
}
pNewHead=pPre;
return pNewHead;
}
};
递归
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead == NULL || pHead->next == NULL)
return pHead;
else
{
ListNode* newHead = ReverseList(pHead->next);
pHead->next->next=pHead;
pHead->next = NULL;
return newHead;
}
}
};