翻转链表是一个常考的经典面试题,是一个程序员必备的基本功
它本身也是单链表题目中非常典型的一道,不少题目的解法以反转链表为基础
(本文语言以Java为例,算法思路是通用的)
东汉太傅陈蕃。其祖父曾任河东太守。不过到了陈蕃一辈,家道中落,不再威显乡里。陈蕃15岁时,曾经独处一个庭院习读诗书。一天,其父的一位老朋友薛勤来看他,看到院里杂草丛生、秽物满地,就对陈蕃说:“孺子何不洒扫以待宾客?”陈蕃当即回答,大丈夫处世,当扫除天下,安事一室乎!这回答让薛勤暗自吃惊,知道此人虽年少却胸怀大志。感悟之余,劝道,一屋不扫,何以扫天下?
如果一个程序员连基本的翻转链表都做不到,那他只能算一个“码农”,永远成为不了一名软件“工程师”!
题目描述
给你单链表的头节点 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
经典的错误,标准的零分
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
ListNode next = curr.next;
while(curr!=null){
curr.next =prev;
prev = curr;
curr = next;
next = curr.next;
}
return prev;
}
}
这段代码的思路没有问题,但运行却会引发空指针异常
这是我一开始写的代码,当时已经明白了使用迭代的思路,却忽视了一个问题
就是个解法的错误是while循环里的最后一行代码,当运行到了最后一个节点的时候,运行到最后一行代码时,就会出现next试图指向null的下一个节点,这时就该报空指针错误了
正解一、迭代
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while(curr!=null){
ListNode next = curr.next;
curr.next =prev;
prev = curr;
curr = next;
}
return prev;
}
}
正解二、递归
未完待续......
思路解析
我使用的简单易懂的迭代思路,我们需要构造3个指针
prev表示前面的节点,curr指向当前节点,next表示之后的节点
从头节点我们开始往后不断遍历
我们使用 curr.next = prev 来反转指针,但这会覆盖掉 curr.next 本来存储的值。
丢掉这个指针之后,链表的后续结点就访问不到了
所以两个指针不够,我们还要一个临时指针next保存 curr 的下一个结点,而且需要在翻转之前就保存好,这就是为啥while循环第一句就是ListNode next = curr.next
以下是While语句里后面三行的图示,也是这段代码的核心思想,不断往后移动
至于为什么返回的是prev节点,因为最后curr和next两个指针都移动到链表外面去了,到最右边都是null了
\
题外话
因为不知道有没有人看
要是点赞有3个,博主马上更新递归解法的代码和思路😂