#206 反转链表
题目
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
思路
迭代法
- 初始化三个指针:
prev: 指向前一个节点,初始为null(因为第一个节点反转后将指向null)
curr: 指向当前正在处理的节点,初始为头节点
next: 用于临时保存下一个节点(在循环中定义) - 使用while循环遍历整个链表:
循环继续的条件是curr != null,即当前节点不为空 - 在每次循环中:
首先保存curr的下一个节点到next,因为我们即将改变curr.next
将curr.next指向prev,实现反转
将prev移动到curr
将curr移动到next - 循环结束后,prev将指向原链表的最后一个节点,它现在成为反转后链表的头节点
- 返回prev作为新的头节点
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
// 初始化三个指针
ListNode prev = null; // 前一个节点,初始为null
ListNode curr = head; // 当前节点,初始为头节点
// 遍历整个链表
while (curr != null) {
// 保存当前节点的下一个节点
ListNode next = curr.next;
// 反转当前节点的指针,使其指向前一个节点
curr.next = prev;
// 移动指针
prev = curr; // 将前一个节点更新为当前节点
curr = next; // 将当前节点更新为下一个节点
}
// 返回新的头节点,即原链表的最后一个节点
return prev;
}
}
复杂复分析
时间复杂度:O(n),其中n是链表的长度,因为我们只遍历了一次链表。
空间复杂度:O(1),因为只使用了固定数量的额外空间(三个指针),不随输入规模变化。