题目描述
输入一个链表,反转链表后,输出新链表的表头。
要求:时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
牛客网给的标签是中等难度,二星,本来昨天时间很晚了,我就想挑一道简单的,这道题是我现在练的链表专题里通过率最高的,结果昨天出了点小问题,今天才做出来
解题思路
整体思路就是遍历链表,然后修改当前指针的next域,指向它在原链表中的前驱结点。这里画了一张图
具体实现方法是:设置三个指针,原链表中的当前指针cur,指向当前结点的前驱结点的指针p,以及指向后继结点的指针q,遍历时将当前结点的next指针设置为它在原链表中的前驱结点cur->next=p;
然后三个指针后移,实现循环,(设置后继结点指针的意义在于实现,因为已经修改了当前结点的next指针,无法在由它找到原链表中的后继结点),p=cur;cur=q;q=q->next;
,出循环的时候(遍历到了最后一个结点),记得修改pHead指针,将原链表中的最后一个结点设置为头结点
还有一种特殊情况,当链表为空或只有一个结点是无须反转,直接返回pHead即可
我遇到的问题
- 系统提示出现段错误,可能是数组越界或堆栈溢出
在链表中遇到这个问题基本上就是非法访问内存,注意在访问结点时一定要判断它是非空的才能访问 - 注意修改原链表中的头结点的next指针,因为我是在循环里修改后继指针的,而第一个结点没有进循环,所以系统会报循环过大超出时间限制的情况,一定要将原链表中的第一个结点的next设置为NULL
源代码
/*
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){
ListNode* p=pHead;
ListNode* cur=p->next;
pHead->next=NULL;
if(cur->next!=NULL){
ListNode* q=cur->next;
while(cur!=NULL){
cur->next=p;
p=cur;
cur=q;
if(q->next!=NULL)
q=q->next;
else
break;
}
}
cur->next=p;
pHead=cur;
}
return pHead;
}
};