题目描述
给你单链表的头节点
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
进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
解题思路
反转单链表是一道经典的链表操作题目。可以使用两种主要的方法来实现:迭代和递归。
1. 迭代方法思路
- 使用三个指针来反转链表:
prev
(前一个节点),curr
(当前节点),和next
(下一个节点)。 - 遍历链表,将当前节点的
next
指针指向前一个节点,更新prev
和curr
指针,直到遍历完成。
2. 递归方法思路
- 递归处理链表的尾部,并将每个节点的
next
指针指向当前节点,从而实现反转。 - 基本的递归策略是:反转链表的其余部分,然后将当前节点追加到反转链表的尾部。
复杂度分析
1. 迭代方法复杂度
- 时间复杂度: O(n)O(n)O(n),其中 nnn 是链表的节点数,每个节点仅遍历一次。
- 空间复杂度: O(1)O(1)O(1),仅使用常量级别的额外空间。
2. 递归方法思路复杂度
- 时间复杂度: O(n)O(n)O(n),其中 nnn 是链表的节点数,每个节点仅处理一次。
- 空间复杂度: O(n)O(n)O(n),递归调用栈的空间复杂度为 O(n)O(n)O(n)。
代码实现
package org.zyf.javabasic.letcode.hot100.list;
import org.zyf.javabasic.letcode.list.base.ListNode;
/**
* @program: zyfboot-javabasic
* @description: 反转链表
* @author: zhangyanfeng
* @create: 2024-08-21 23:54
**/
public class ReverseListSolution {
public ListNode reverseList1(ListNode head) {
ListNode prev = null; // 前一个节点
ListNode curr = head; // 当前节点
while (curr != null) {
ListNode next = curr.next; // 保存下一个节点
curr.next = prev; // 反转当前节点的指针
prev = curr; // 更新前一个节点
curr = next; // 移动到下一个节点
}
return prev; // 返回新头节点
}
public ListNode reverseList2(ListNode head) {
// 递归基准条件:链表为空或只有一个节点
if (head == null || head.next == null) {
return head;
}
// 递归反转链表的剩余部分
ListNode newHead = reverseList2(head.next);
// 反转当前节点和下一个节点
head.next.next = head;
head.next = null;
return newHead; // 返回新的头节点
}
public static void main(String[] args) {
ReverseListSolution solution = new ReverseListSolution();
// 测试用例 1: 普通链表
System.out.println("Test Case 1: [1, 2, 3, 4, 5]");
ListNode head1 = new ListNode(1);
head1.next = new ListNode(2);
head1.next.next = new ListNode(3);
head1.next.next.next = new ListNode(4);
head1.next.next.next.next = new ListNode(5);
ListNode result1 = solution.reverseList1(head1);
printList(result1);
// 测试用例 2: 两个节点的链表
System.out.println("Test Case 2: [1, 2]");
ListNode head2 = new ListNode(1);
head2.next = new ListNode(2);
ListNode result2 = solution.reverseList1(head2);
printList(result2);
// 测试用例 3: 空链表
System.out.println("Test Case 3: []");
ListNode head3 = null;
ListNode result3 = solution.reverseList2(head3);
printList(result3);
// 测试用例 4: 单节点链表
System.out.println("Test Case 4: [1]");
ListNode head4 = new ListNode(1);
ListNode result4 = solution.reverseList2(head4);
printList(result4);
}
// 打印链表的方法
public static void printList(ListNode head) {
if (head == null) {
System.out.println("null");
return;
}
ListNode curr = head;
while (curr != null) {
System.out.print(curr.val + " ");
curr = curr.next;
}
System.out.println();
}
}
具体可参考:https://zyfcodes.blog.csdn.net/article/details/141401712