- 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
示例 2:
示例 3:
提示:
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
方法一:迭代(双指针)
思路:
设置当前节点cur,前一节点pre,后一节点next;
遍历链表,更改cur与pre节点的连接关系,即cur->next=pre
。因为pre的初始值为反转后链表的最后一个节点指向的next,因此pre初始化为nullptr。然后更新cur为下一节点。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* pre = nullptr;
while(cur){
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
};
复杂度分析:
- 时间复杂度:O(n);
- 空间复杂度:O(1);
方式二:栈
遍历链表,将节点分别存入栈中,然后创建新的头节点,将栈中的节点分别取出,连接在新的头节点后面。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head==nullptr) return head;
ListNode* cur = head;
stack<ListNode*> node;
while(cur!=nullptr){
node.push(cur);
cur=cur->next;
}
ListNode* new_head=new ListNode(0);
ListNode* p = new_head;
while(node.size()){
ListNode* cur = node.top();
node.pop();
p->next = cur;
p = p->next;
}
p->next = nullptr;
return new_head->next;
}
};
复杂度分析:
- 时间复杂度:O(n);
- 空间复杂度:O(n);
方式三:递归
class Solution {
public:
ListNode* help(ListNode* pre, ListNode* cur){
if(cur==nullptr) return pre;
ListNode* temp = cur->next;
cur->next = pre;
return help(cur, temp);
}
ListNode* reverseList(ListNode* head) {
return help(nullptr, head);
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr || head->next == nullptr) return head;
ListNode* new_head = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return new_head;
}
};
复杂度分析:
- 时间复杂度:O(n);
- 空间复杂度:O(n);