题目来源:反转链表_牛客题霸_牛客网
描述
给定一个单链表的头结点pHead,长度为n,反转该链表后,返回新链表的表头。
数据范围: n\leq1000n≤1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。
如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
我的代码:
借助stack,哈哈,最近很喜欢用栈。先把链表中的节点一个个压入栈,然后再一个个输出。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==nullptr){
return pHead;
}
ListNode* l;
stack<ListNode*> s;
for(l=pHead;l!=nullptr;l=l->next){
s.push(l);
}//把结构体中的数据压入栈中
l=s.top();
s.pop();
pHead=l;//转换头部
for(s;!s.empty();s){
ListNode* n=s.top();
l->next=n;
l=l->next;
s.pop();
}
l->next=nullptr;//最后的节点的指向为null.(一直忘了这一个,报错输出超限)
return pHead;
}
};
可以看出虽然结果正确,但是运行时间和占用内存都不是很好。
题目答案:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode *pre = nullptr;
ListNode *cur = pHead;
ListNode *nex = nullptr; // 这里可以指向nullptr,循环里面要重新指向
while (cur) {
nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
return pre;
}
};
可以看出给出的结果在时间和空间上都有提升。在时间上,我们只需要遍历一次链表;在空间上,我们无需借助栈,直接在链表中进行反向转换。(题目中的解答中还给了一种借助vector和reverse()的方法,其实和stack的思想一致,只是换了一种媒介。)
(如果觉得解答有问题,或者有更好的方法,欢迎讨论哦~)