206.反转链表
206.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
进阶:
链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
206.2 题解
迭代法反转链表
// 方法一:迭代法反转链表
// 遍历链表,依次将当前节点的 next 指针指向前一个节点,实现链表反转
static ListNode ReverseList1(ListNode head)
{
// 如果链表为空或只有一个节点,直接返回原链表头节点
if (head == null || head.next == null)
return head;
// 初始化前一个节点为 null,当前节点为链表头节点
ListNode pre = null;
ListNode cur = head;
// 遍历链表节点
while (cur != null)
{
// 临时变量存储当前节点的下一个节点
ListNode nextTemp = cur.next;
// 反转当前节点的指针方向,指向前一个节点
cur.next = pre;
// 前一个节点后移
pre = cur;
// 当前节点后移
cur = nextTemp;
}
// 循环结束后,pre 指向反转后的链表头节点
return pre;
}
递归法反转链表
// 方法二:递归法反转链表
// 递归到链表末尾,然后回溯过程中修改节点的 next 指针实现链表反转
static ListNode ReverseList2(ListNode head)
{
// 递归终止条件:链表为空或只有一个节点
if (head == null || head.next == null)
{
return head;
}
// 递归调用反转后的链表的头结点 比如12345 到了第4层会返回reversed为5 当前head是4
ListNode reversed = ReverseList2(head.next);
// 修改当前节点的 next 指针,使其指向当前节点,实现链表反转
// 比如12345 到了第4层head是4 head.next是5 head.next.next就是让5指向4
head.next.next = head;
//当前head就指向空了 因为其他节点会限制
head.next = null;
return reversed; // 反转后的链表头节点为 reversed
}
206.3 代码
using System;
class ListNode
{
public int val;
public ListNode next;
public ListNode(int val = 0, ListNode next = null)
{
this.val = val;
this.next = next;
}
}
class Program
{
static void Main()
{
#region 题目
// 给你单链表的头节点 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
// 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
#endregion
#region 测试
// 示例 1
ListNode head1 = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
Console.WriteLine("示例1 原链表:");
PrintList(head1);
ListNode reversed1 = ReverseList1(head1);
Console.WriteLine("示例1 方法1 反转后的链表:");
PrintList(reversed1);
ListNode head1_2 = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
Console.WriteLine("示例1 原链表:");
PrintList(head1_2);
ListNode reversed1_2 = ReverseList2(head1_2);
Console.WriteLine("示例1 方法2 反转后的链表:");
PrintList(reversed1_2);
// 示例 2
ListNode head2 = new ListNode(1, new ListNode(2));
Console.WriteLine("示例2 原链表:");
PrintList(head2);
ListNode reversed2 = ReverseList1(head2);
Console.WriteLine("示例2 方法1 反转后的链表:");
PrintList(reversed2);
ListNode head2_2 = new ListNode(1, new ListNode(2));
Console.WriteLine("示例2 原链表:");
PrintList(head2_2);
ListNode reversed2_2 = ReverseList2(head2_2);
Console.WriteLine("示例2 方法2 反转后的链表:");
PrintList(reversed2_2);
// 示例 3
ListNode head3 = null;
Console.WriteLine("示例3 原链表:");
PrintList(head3);
ListNode reversed3 = ReverseList1(head3);
Console.WriteLine("示例3 方法1 反转后的链表:");
PrintList(reversed3);
ListNode head3_2 = null;
Console.WriteLine("示例3 原链表:");
PrintList(head3_2);
ListNode reversed3_2 = ReverseList2(head3_2);
Console.WriteLine("示例3 方法2 反转后的链表:");
PrintList(reversed3_2);
#endregion
}
#region 答案
// 方法一:迭代法反转链表
// 遍历链表,依次将当前节点的 next 指针指向前一个节点,实现链表反转
static ListNode ReverseList1(ListNode head)
{
// 如果链表为空或只有一个节点,直接返回原链表头节点
if (head == null || head.next == null)
return head;
// 初始化前一个节点为 null,当前节点为链表头节点
ListNode pre = null;
ListNode cur = head;
// 遍历链表节点
while (cur != null)
{
// 临时变量存储当前节点的下一个节点
ListNode nextTemp = cur.next;
// 反转当前节点的指针方向,指向前一个节点
cur.next = pre;
// 前一个节点后移
pre = cur;
// 当前节点后移
cur = nextTemp;
}
// 循环结束后,pre 指向反转后的链表头节点
return pre;
}
// 方法二:递归法反转链表
// 递归到链表末尾,然后回溯过程中修改节点的 next 指针实现链表反转
static ListNode ReverseList2(ListNode head)
{
// 递归终止条件:链表为空或只有一个节点
if (head == null || head.next == null)
{
return head;
}
// 递归调用反转后的链表的头结点 比如12345 到了第4层会返回reversed为5 当前head是4
ListNode reversed = ReverseList2(head.next);
// 修改当前节点的 next 指针,使其指向当前节点,实现链表反转
// 比如12345 到了第4层head是4 head.next是5 head.next.next就是让5指向4
head.next.next = head;
//当前head就指向空了 因为其他节点会限制
head.next = null;
return reversed; // 反转后的链表头节点为 reversed
}
#endregion
#region 辅助方法
// 打印链表
static void PrintList(ListNode head)
{
ListNode current = head;
while (current != null)
{
Console.Write($"{current.val} -> ");
current = current.next;
}
Console.WriteLine("null");
}
#endregion
}
206.4 运行结果
示例1 原链表:
1 -> 2 -> 3 -> 4 -> 5 -> null
示例1 方法1 反转后的链表:
5 -> 4 -> 3 -> 2 -> 1 -> null
示例1 原链表:
1 -> 2 -> 3 -> 4 -> 5 -> null
示例1 方法2 反转后的链表:
5 -> 4 -> 3 -> 2 -> 1 -> null
示例2 原链表:
1 -> 2 -> null
示例2 方法1 反转后的链表:
2 -> 1 -> null
示例2 原链表:
1 -> 2 -> null
示例2 方法2 反转后的链表:
2 -> 1 -> null
示例3 原链表:
null
示例3 方法1 反转后的链表:
null
示例3 原链表:
null
示例3 方法2 反转后的链表:
null
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com