LeetCode 剑指 Offer 24. 反转链表
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 剑指 Offer 24. 反转链表相关的知识,希望对你有一定的参考价值。
题目描述
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
迭代
假设链表为1->2->3->null
,我们想要把它反转为null->3->2->1
。
在遍历链表时,将当前节点的next指针改为执行前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
Java
class Solution
public ListNode reverseList(ListNode head)
ListNode prev = null;
ListNode curr = head;
while (curr != null)
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
return prev;
Cpp
class Solution
public:
ListNode* reverseList(ListNode* head)
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr)
ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
return prev;
;
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n),其中 n 是链表的长度。需要遍历链表一次。
- 空间复杂度: O ( 1 ) O(1) O(1)。
递归
递归版本稍微复杂一些,其关键在于反向工作。假设链表的其余部分已经被反转,现在应该如何反转它前面的部分?
注意n1的下一个节点必须执行null,否则可能出现环。
Java
class Solution
public ListNode reverseList(ListNode head)
if (head == null || head.next == null)
return head;
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
Cpp
class Solution
public:
ListNode* reverseList(ListNode* head)
if (!head || !head->next)
return head;
ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
;
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n),其中 n 是链表的长度。需要对链表的每个节点进行反转操作。
- 空间复杂度: O ( n ) O(n) O(n),其中 n 是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 n 层。
理解
为什么可以使用递归?
- 大问题拆分为两个子问题(头结点及非头结点)
- 子问题求解方式和大问题一样
- 存在最小的子问题
我们想反转链表,那么可以递归到尾部节点(此时尾结点变为真正的头结点,所以在递归出栈中一直return p
),从尾结点开始出栈回溯,出栈的过程中修改head.next.next = head,head.next = null
。
加油!
感谢!
努力!
以上是关于LeetCode 剑指 Offer 24. 反转链表的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Algorithm 剑指 Offer 24. 反转链表