力扣题目链接:206. 反转链表
牛客题目链接:BM1 反转链表
前言
反转链表作为链表操作的基础是重中之重,以后做比较难的链表题目也可能会需要嵌入反转链表的代码,所以一定要多多练习
方法一:构造新链表(构造新节点)
思路:构造一个新的链表,从旧链表依次拿到每个节点,根据旧链表创建新节点添加至新链表头部,完成后新链表是倒序的
public ListNode reverseList (ListNode head) {
//新链表的头节点,还没有元素,定义为null
ListNode n1 = null;
//设置一个指针,用来遍历旧链表
ListNode p = head;
//循环遍历旧链表
while(p != null){
//根据旧链表的值创建新节点,把新节点的next指针设置为新链表的头节点,并更新新链表的头节点
n1 = new ListNode(p.val,n1);
p = p.next;
}
//返回新链表的头节点
return n1;
}
方法二:构造新链表(不构造新节点)
与方法一类似,构造一个新链表,从旧链表头部移除节点,添加到新链表头部,完成后新链表是倒序的————是不是看完后很蒙,和方法一一样啊,方法一是根据旧链表的值构造节点,方法二是直接使用旧链表的节点,没有创建新的节点
public ListNode reverseList (ListNode head) {
ListNode p1 = head;
ListNode p2 = null;
while(true){
//记录旧链表的头指针
ListNode first = head;
//如果旧链表的指针指向null就退出循环
if(first == null){
break;
}
//旧链表向前一步
head = head.next;
//将旧链表的头指针指向新链表的头
first.next = p2;
//更新新链表的头指针
p2 = first;
}
return p2;
}
方法三:递归
递归,找到并返回最后一个节点记录为新节点,从倒数第二个开始,将后一个节点的指针指向自己(也就是p.next.next = p),再将自己的next指向null,避免死循环
public ListNode reverseList(ListNode head) {
//递归结束条件和链表为空的条件判断
if(head == null || head.next == null){
return head;
}
//递归调用,当递归到最后一个节点时返回,也就是反转后的头节点,我们用变量记录下来
ListNode newHead = reverseList(head.next);
//从倒数第二个节点开始,将后一个节点的指针指向自己
head.next.next = head;
//将自己的next指针指向null,避免死循环
head.next = null;
//返回头节点
return newHead;
}
方法四:双指针
双指针法:定义两个指针,都先指向头节点。将旧链表指针的下一个节点断开,插入到链表的头节点处,更新新链表的指针
public ListNode reverseList(ListNode head) {
//判断链表为空的情况
if(head == null){
return head;
}
//定义新链表指针
ListNode n1 = head;
//定义旧链表指针
ListNode o1 = head;
//判断条件,旧链表指针的下一个节点不为null
while(o1.next != null){
//记录旧链表的下一个指针
ListNode temp = o1.next;
//跳过旧链表指针的下一个节点
o1.next = o1.next.next;
//将跳过的指针指向头
temp.next = n1;
//更新新链表的指针
n1 = temp;
}
return n1;
}
方法五:遍历
遍历法,定义三个指针,从前向后遍历一遍并更改指针的指向
public ListNode reverseList(ListNode head) {
//前指针
ListNode prev = null;
//当前指针
ListNode p = head;
//后一个指针
ListNode next = null;
while(p != null){
//后一个指针,为什么要在循环里面赋值呢?避免head为null的情况
next = p.next;
//将当前指针指向前一个
p.next = prev;
//更新前指针
prev = p;
//更新当前指针
p = next;
}
//这里为什么要返回前指针,因为p在循环里面被更新为null,循环才不能进行,所以循环走完后prev的位置是头节点的位置
return prev;
}
总结
本文讲解了反转指针的五种方法,反转指针是链表操作中的基础,但是特别重要,大家快去练习把~