反转链表

206. 反转链表 - 力扣(LeetCode)

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

方法一

算法思路:

  1. next = cur.next储存起来
  2. cur.next = pre
  3. precur向后移

代码实现:

class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while(cur != null){
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),其中nn是链表的长度,需要遍历链表一次。
  • 空间复杂度:O(1)O(1)

方法二:递归

假设链表为:

1→2→3→4→5

某一时刻,我们处于如下状态:

1→2→3←4←5

我们希望3的下一个节点指向2,所以2.next.next = 2

需要注意的是,头结点的下一个节点必须指向\varnothing,不然可能会产生环。

代码实现:

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;
}
}

复杂度分析:

  • 时间复杂度:O(n)O(n),其中 nn 是链表的长度。需要对链表的每个节点进行反转操作。

  • 空间复杂度:O(n)O(n),其中 nn是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 nn 层。

参考

反转链表 - 反转链表 - 力扣(LeetCode)