反转链表
1、题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
提示
- 链表中节点的数目范围是 [0, 5000]
- -5000 <= Node.val <= 5000
2、解法一 —— 头插法
2.1 思路
- 1 创建一个新链表
- 2 遍历原链表,头插到新链表中
- 步骤
1、创建dummyHead为新链表的虚拟头节点: ListNode dummyHead=new ListNode(5001);
2、依次遍历原链表,创建新节点:
第一次:新节点值为头节点 : ListNode node=new ListNode(head.val);
3、node指向dummyHead的下一个节点,
当node为头节点时,dummyHead.next=null,此时node为头节点
将虚拟头节点连接到当前节点node,dummyHead.next=node;
head向后移动一位
继续创建新节点,值为2
2.2 头插法代码
// 1.头插法
public ListNode reverseList(ListNode head) {
// 链表为空 或者只有一个节点
if(head==null||head.next==null){
return head;
}
// 新链表的虚拟头节点
ListNode dummyHead=new ListNode(5001);
//边遍历原链表,边创建新节点,将新节点依次头插新链表
while(head!=null){
// 创建节点(原链表[头节点,尾节点])
ListNode node=new ListNode(head.val);
// 当为头节点时,dummyHead.next为null
node.next=dummyHead.next; // 将当前节点插入原先链表的头
dummyHead.next=node; // 更新当前节点
head=head.next; // 遍历原先链表
}
return dummyHead.next;
}
3、解法二 —— 原地移动 O(1) 改变原链表的指向
3.1 思路
回文链表只是 原链表的next不再指向后继转而指向前驱
cur: 表示当前需要处理的节点
prev: 当前节点的前驱
让
cur.next=prev;
cur 和prev向后移动
3.2 代码
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode dummyHead=new ListNode(5001);
ListNode prev=null;
// 从刚开始第一个节点开始处理
ListNode cur=head;
while(cur!=null){
// 保存当前操作节点的下一个节点地址
ListNode next=cur.next;
cur.next=prev;
prev=cur;
cur=next;
}
return prev;
}
4、解法三 —— 递归法
4.1 思路
写一个方法,传入一个以head为头节点的链表,该方法就可以将此链表反转并返回反转后的链表头节点
public ListNode reverseList(ListNode head) {
}
4.2 代码
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode sec=head.next;
// 反转第二个节点之后的子链表
ListNode newHead=reverseList(head.next);
sec.next=head;
head.next=null;
return newHead;
}