反转链表
题目描述
输入一个链表,反转链表,输出新链表的表头。
示例
输入
{1,2,3}
返回值
{3,2,1}
题解
方法一:构造新链表
如果内存要求不高,可以先将单链表的每一个指针都存下来,然后再按顺序逐个构造新的链表。
时间复杂度:O(n)
空间复杂度:O(n),使用了vector来存储
/*
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;
vector<ListNode*> vec;
while(pHead){
vec.push_back(pHead);
pHead = pHead->next;
}
// 反转vector,也可以逆向遍历
reverse(vec.begin(), vec.end());
ListNode* head = vec[0];
ListNode* cur = head;
for(int i=0; i<vec.size(); i++){
cur->next = vec[i];
cur = cur->next;
}
cur->next = nullptr;
return head;
};
方法二:头插法
初始化3个指针:
- result指针指向已经反转好的链表的最后一个节点,最开始没有反转,所以指向nullptr。
- p指针指向待反转链表的第一个节点,最开始是第一个节点等待反转,所以指向pHead。
循环执行以下操作:
-
ListNode* temp = p->next将p的下一个节点进行保存。
-
p->next = result将反转后的result链表作为当前节点的后续节点。
-
result = p反转后的链表添加一个新的节点。
-
p = temp寻找下一个待插入节点。
/*
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* result = NULL;
ListNode* p = pHead;
while(p){
ListNode* temp = p->next;
p->next = result;
result = p;
p = temp;
}
return result;
};
方法三:递归
递归的模板:终止条件、逻辑处理(可能有,可能没有)递归调用、逻辑处理(可能有,可能没有)。
终止条件就是链表为空或者链表没有尾节点,直接返回pHead。
递归调用是从当前节点的下一个节点开始进行,逻辑处理就是把当前的节点连接到递归之后的链表末尾
/*
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* result = ReverseList(pHead->next);// 走到链表的末端
pHead->next->next = pHead;// 将当前节点设置为后面节点的后续节点
pHead->next = NULL;
return result;
};
方法四:使用栈
因为栈本身是先进后出,把链表的每个节点逐个入栈,当全部入栈完之后,再逐个出栈,出栈时把出栈节点连接成为反转之后的链表。
/*
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* cur = pHead;
stack<ListNode* > s;
while(cur->next) {// 入栈
s.push(cur);
cur = cur->next;
}
ListNode* result = cur;
while( !s.empty()) {// 出栈
cur->next = s.top();
cur = cur->next;
s.pop();
}
cur->next = NULL;
return result;
};