题目描述
给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
解题思路1:
结点不变,改变指针的指向
定义三个指针,分别为pre,cur和next
cur为当前需要操作的指针,pre为待返转链表中cur的前一个结点指针,next为待返转链表中cur的后一个结点指针
大致操作为:
代码:
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode *pre,*cur,*next;
pre = NULL; //最开始先指向NULL,因为第一个结点反转后是最后一个结点,应当指向NULL
cur = pHead;
next = NULL;
while(cur)
{
next = cur->next; //在链表没断之前先用next指针保存后一段链表
cur->next = pre; //设置目标指针反转之后next指针的指向
pre = cur; //pre指针后移
cur = next; //当前指针向后移
}
return pre; //最后cur指针是指向NULL的,所以返回pre指针
}
};
解题思路2:
遍历找到最后一个结点和倒数第二个结点,然后把倒数第一个结点取出来当作头结点,倒数第二个结点的next指针指向NULL,然后从原链表的头结点开始遍历并以头插法插入到最后一个结点后面。
代码:
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead == NULL || pHead->next == NULL)
return pHead;
ListNode *last,*prelast,*s,*p;
p = pHead;
while(p != NULL)
{
if(p->next->next == NULL)
{
prelast = (ListNode*)malloc(sizeof(ListNode));//取出倒数第二个结点
prelast->val=p->val;
prelast->next = NULL; //倒数第二个结点作为当前链表的最后一个结点,指向NULL
}
if(p->next == NULL)
{
last = (ListNode*)malloc(sizeof(ListNode));//倒数第一个结点
last->val=p->val;
last->next = NULL; //将倒数第一个结点作为头结点
break;
}
p = p->next;
}
p = pHead;
while(p->next != NULL) //头插
{
s = p;
p = p->next;
s->next = last->next;
last->next = s;
}
return last;
}
};