目录
1.题目描述
难度:简单
给你单链表的头节点 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
2.题目解答
方法一:双指针法
解题思路
1.首先定义一个curr
指针,指向头结点,再定义一个prev
指针,初始化为null
。
2.接下来要将 curr->next
指向prev
,需要把 curr->next
节点用tmpt
指针保存一下。
3.接下来依次循环移动prev
和curr
指针。
4.最后,curr
指针已经指向了null
,循环结束,链表也反转完毕了,此时prev
指针就指向了新的头结点。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
ListNode temp = null;
while (curr != null) {
// 保存下一个节点
temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
return prev;
}
}
方法二:从前往后递归
解题思路
每次递归只反转相邻两个节点的顺序。
class Solution {
public ListNode reverseList(ListNode head) {
return reverseNode(null, head);
}
private ListNode reverseNode(ListNode prev, ListNode curr) {
if (curr == null) {
return prev;
}
// 保存下一个节点
ListNode temp = curr.next;
// 反转节点
curr.next = prev;
return reverseNode(curr, temp);
}
}
方法三:从后往前递归
class Solution {
public ListNode reverseList(ListNode head) {
// 边缘条件判断
if (head == null) {
return null;
}
if (head.next == null) {
return head;
}
// 递归调用,翻转从第二个节点开始往后的链表
ListNode last = reverseList(head.next);
// 翻转头节点与第二个节点的指向
head.next.next = head;
// 此时头节点变成尾节点,需要指向null
head.next = null;
return last;
}
}