思路一:迭代
遍历链表,逐步反转每个节点的指针方向
0: 初始状态
1:修改后继指针:current->next = front;
更新指针:front = current;
current = next;
2:继续修改后继:current->next = front;
并更新指针:front = current;
current = next;
3:重复上述步骤
最终current指针到达链表的最后一个节点处,并完成反转:
因此最终应返回front
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr){
return nullptr;
}
ListNode* front = nullptr;//用于保存反转链表过程中的前驱节点,初始为空
ListNode* current = head;//用于保存当前节点,初始为头节点
//遍历链表
while(current != nullptr){
// 保存当前节点的下一个节点,防止丢失链表后续部分
ListNode* nxt = current->next;
//反转链表,使当前节点的后继为之前的前驱
current->next = front;
//更新前驱
front = current;
//更新当前节点
current = nxt;
}
//返回反转链表的头结点
return front;
}
};
- 时间复杂度:O(N)
- 空间复杂度:O(1)
思路二:递归
不断递归调用该函数,使当前节点的后继的后继为当前节点
例如:1 - > 2 - > 3 - > 4
第一层递归:head:1 reverseList(2);
第二层递归:head:2 reverseList(3);
第三层递归:head:3 reverseList(4);
第四层递归:head:4 此时4->next==nullptr 返回4
返回第三层调用:head:3 此时修改4->next为3 将3和4断开 返回4
返回第二层调用:head:2 此时修改3->next为2 将2和3断开 返回4返回第一层调用:head:1 此时修改2->next为1 将1和2断开 返回4
递归完成 返回新链头
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr){
return nullptr;
}
if(head->next == nullptr){
return head;
}
ListNode* newHead = reverseList(head->next);
head->next->next = head;//使当前节点的后继的后继为当前节点
head->next = nullptr;//断链
//返回反转链表的头结点
return newHead;
}
};
- 时间复杂度:O(N)
- 空间复杂度:O(N)