反转链表笔记
给定一个链表头结点,要求将这个链表进行翻转,这道题在面试手撕代码的时候很容易遇到,找实习面试的时候真是蠢啊都没有想起来双指针解法。现在得好好总结总结记记笔记。
双指针法
要翻转这个链表就要改变所有指针的指向,如果我们把当前节点curr的next指针指向它的前一个节点pre过后,就无法定位curr原本的下一个节点,所以需要在翻转当前节点时使用temp来保存下一个节点。
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
//双指针法
if(pHead ==nullptr){
return pHead;
}
ListNode* curr=pHead;
ListNode* pre=nullptr;
ListNode* temp=curr->next;//记录当前待翻转结点的下一个节点
while(curr!=nullptr){
curr->next=pre;//翻转当前节点
pre=curr;//将pre调整为当前节点
curr=temp; //调整当前节点为下一个节点
temp=curr->next; //记录下一个节点的下一个节点
}
//返回pre
return pre;
}
};
双指针法的时间复杂度为O(n),空间复杂度为O(1)。
递归法
还可以使用递归法,其思想是以当前节点curr和它的前一个节点pre为参数进行递归,递归结束的标志是当前节点为nullptr,然后从下至上返回翻转后的头节点,并且在递归返回的时候更改curr指针的指向,让它指向pre。具体的代码如下:
class Solution {
public:
ListNode* Reverse(ListNode* pre,ListNode* curr){
if(curr==nullptr){
return pre;
}
ListNode* res=Reverse(curr, curr->next);
curr->next=pre;
return res;
}
ListNode* ReverseList(ListNode* pHead) {
//递归法
return Reverse(nullptr, pHead);
}
};
递归法的时间复杂度为O(n),但是空间复杂度也要O(n)。