一 解析
链表内包含一个 val 数值和一个指向后继节点的引用 next。要做的就是把这个链表节点内的指针指向它的前驱节点。
因为这是一个单向链表,所以光凭借这个链表本身的数据还无法直接获取每个节点的前驱节点。 所以这里我们需要一个额外的变量,来获取并保存每个节点的前驱节点。
初始化链表的头节点的前驱节点是 null。
这个题看起来很简单,但是很多时候,在我一段时间不接触这个题之后再来做的时候,还是会出错。为了把这个题彻彻底底地梳理清楚,还是画图来处理的比较好。
问题的核心,在于几个指针的移动过程,梳理清楚循环过程中指针的移动,这个题就理清楚了。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode curr = head;
ListNode prev = null;
while (curr != null) {
ListNode item = curr.next;
curr.next = prev;
prev = curr;
curr = item;
}
return prev;
}
}
- 进入循环体前,声明了一个值为 null 的前驱节点,这个是符合场景的,因为初始链表的头节点的前驱节点就是 null。
![](https://img.haomeiwen.com/i4705286/50d9f44660f7e9ef.png)
-
循环体第一步,声明了一个新的指针,保存的是当前节点的后继节点引用。
step1
- 循环体第二步,将当前节点的后继节点引用修改为指向前驱节点。这里可以看到第一步代码的作用了,只有先用指针保留对原来的后继节点的引用,在修改了当前节点的后继引用指向之后,才能保持对链表后半段的控制。没有这个 item 指针,我们就无法继续控制断开连接引用的两段链表。
step2
- 第三步,将前驱节点指针指向修改为指向当前节点。原来的链表头节点的前驱节点是 null,但是头节点之后的节点,它们的前驱节点就都不是 null 了,所以需要在循环体内不断更新这个前驱节点指针的指向。
step3
- 第四步,将当前节点指针引用修改为指向循环体内保存的后继节点。节点 1 的引用指向关系已经修改完成了,下一轮循环需要处理的是节点 2。
step4
网友评论