☰
Leetcode hot100 反转链表【简单】
2026/10/13 2:32:36 网站建设 项目流程

法(一) new新结点

这个题直觉就是,一边从head节点读原链表,一边从尾结点生成新链表。

/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode reverseList(ListNode head) { ListNode lastOne = null; //上一个生成的结点 ListNode newNode = null; //新生成的结点 while (head != null) { newNode = new ListNode(head.val); newNode.next=lastOne; lastOne = newNode; head = head.next; } return newNode; } }

当然,还能想到一个脑回路更简单(大脑更喜欢)的方式,先遍历一遍原链表,把值存到数组里,然后倒序遍历数组,从头节点开始生成新链表。这两种方法都需要new,空间复杂度一个是O(n),一个是O(2n)

法(二)不用new新节点

链表题一定要画图哦,这个题是三指针。

先看三个指针都在链表中间的普通情况,能写出以下递推关系:

now.next=pre; pre=now; now=next; next=next.next;

再看①只有两个结点时 ②走到尾结点的时候 这两种情况,根据这两种情况写出退出循环的条件。

if(now!=null) next=next.next; else break;

完整代码:

/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode reverseList(ListNode head) { //特殊情况 if(head==null) return null; //特殊情况 if(head.next==null){ return head; } ListNode pre = head; ListNode now = head.next; ListNode next = now.next; //新的处理尾结点.next=null pre.next=null; while(true){ now.next=pre; pre=now; now=next; if(now!=null) next=next.next; else break; } return pre; } }

法(二)递归

法(一)就是最简单的做法了,别问为什么,是进阶要求。

递归出口:依然按照我的一贯用例,第n轮出来。再提醒一下是否是第n轮出来看的是你递归出口的判断if(xxx==null)写在整个方法的最前面,可别理解成了root==null就是第n轮,root.next==null就是提前一轮出来。

递归方法定义:很简单,因为跟原题的要求一样。定义reverseList(head):把head为头结点的链表反转过来。因为跟原题要求的一样,所以不用重写方法,题目给的reverseList方法就可以是我们的递归方法。

递推关系的语义表达:把head为头结点的链表反转过来,相当于把head后面的所有结点翻转过来,然后反转结果的尾结点指向head,head的next再指向null。

根据语义表达写出递推公式:

ListNode head后面所有结点的反转结果behindList= reverseList(head.next);

//找到反转结果的尾结点

while(behindList!=null){ behindList=behindList.next;}

//反转结果的尾结点指向head

behindList.next=head;

//head指向null

head.next=null;

/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode reverseList(ListNode head) { //特殊情况,非递归出口。 if(head==null) return null; //递归出口 if(head.next==null){ return head; } ListNode behindList = reverseList(head.next); ListNode temp = behindList; //得到尾结点 while(temp.next!=null){ temp=temp.next; } temp.next = head; head.next=null; return behindList; } }

当子方法翻转完,处理结点之间连接的时候,除了我上面那种简单的(大脑喜欢的)方式。还有一种写法。

以原链表是1->2->3->4,head是1为例。2->3->4反转后尾结点是2,而反转前的head.next就是2,现在head.next.next就表示尾结点2的next要连接什么,连接反转前的头结点呀!也就是head.next.next=head;

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询