您现在的位置是:首页 >技术教程 >剑指 Offer 24. 反转链表网站首页技术教程
剑指 Offer 24. 反转链表
? 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。
? 个人主页:不 良
? 系列专栏:?剑指 Offer 链表
? 学习格言:博观而约取,厚积而薄发
? 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同成长! ?
剑指 Offer 24. 反转链表
题目:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
思路一:
双指针法:可以通过改变链表中节点的
next
指针的指向从而实现链表的反转。1.设置两个节点
prev
和cur
,cur
表示当前节点,prev
表示当前节点的上一个节点,初始状态设置为prev = nullptr; cur = head
;再设置一个结点tmp
记录cur
的下一个结点,即tmp = cur->next
;2.改变
cur
结点next
指针的指向,让其指向前一个结点prev
,然后再通过prev = cur; cur = tmp; tmp = cur->next
更新cur
节点、prev
节点和tmp
节点;3.依次向后循环,当
cur
为空的时候,说明已经遍历完所有的节点,此时prev
指向的节点就是反转后链表的头节点,返回的时候返回prev
。
代码如下:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* prev = nullptr;
while(cur)
{
ListNode* tmp = cur->next; //保存cur的下一个结点
cur->next = prev;
prev = cur;
cur = tmp;
}
return prev;
}
};
时间复杂度:
O(N)
空间复杂度:
O(1)
思路二:
递归:递归法和双指针法的逻辑相同,也是通过改变指针的指向从而实现反转。
1.递归函数中当
cur
不为空的时候,先记录下cur
节点的下一个节点,再改变cur
节点的next
指针使其指向prev
;2.发生递归,递归参数中的
cur
和tmp
传到下一层函数后,cur
充当prev
,tmp
充当cur
;3.当
cur
为空时递归结束,返回prev
结点,此时的prev
结点就是反转后的头结点;双指针法中的循环以及
pre = cur; cur = temp;
通过递归实现了。
代码如下:
class Solution {
public:
ListNode* Reverse(ListNode* prev,ListNode* cur)
{
if(cur == nullptr)
{
//当cur为空的时候,已经遍历完成,此时prev就是反转后链表的头节点
return prev;
}
ListNode* tmp = cur->next;
cur->next = prev;//改变cur的next指针指向
return Reverse(cur,tmp);
}
ListNode* reverseList(ListNode* head) {
return Reverse(nullptr,head);
}
};
时间复杂度:
O(N)
空间复杂度:
O(N)