文章目录
需求
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例2:
输入:head = [1,2]
输出:[2,1]
示例 3:输入:head = []
输出:[]
分析
初始化:我们使用两个指针,prev 和 current。prev 用来指向反转后的链表的前一个节点(初始时为 None),current 用来遍历原链表(初始时为 head)。
遍历链表:
- 先保存当前节点的下一个节点 next_node。
- 将当前节点的 next 指针指向 prev,实现反转操作。
- 更新 prev 为当前节点。
- 更新 current 为 next_node,继续遍历。
返回新头节点:当 current 变为 None 时,prev 就是新链表的头节点,返回它即可。
双指针法
java
public ListNode reverseList(ListNode head) {
if( head == null || head.next == null ){
return head;
}
ListNode pre = null;
ListNode cur = head;
while( cur != null ){
// 先把cur的下一个节点拿出来
ListNode nextNode = cur.next;
// 将 cur 的下一个指向前一个
cur.next = pre;
pre = cur;
cur = nextNode;
}
return pre;
}
执行结果:
递归
上面的代码很容易改写为递归的写法:
java
if( head == null || head.next == null ){
return head;
}
return reverseList( null, head );
}
private ListNode reverseList(ListNode pre, ListNode cur) {
if( cur == null ){
return pre;
}
// 拿出cur的下一个
ListNode nextNode = cur.next;
cur.next = pre;
return reverseList( cur, nextNode );
}
递归终止条件:
if (cur == null):当遍历到链表的末尾时(即 cur 为 null),返回 pre,这是反转后新链表的头节点。
反转节点:
ListNode nextNode = cur.next;:保存当前节点的下一个节点,以便后续操作。
cur.next = pre;:将当前节点的 next 指针指向前一个节点 pre,这一步是反转指针的核心操作。
递归调用:
return reverseList(cur, nextNode);:调用自身,传入当前节点 cur 作为新的前一个节点,和保存的 nextNode 作为当前节点,以继续反转剩余的链表。
运行结果:
结尾
以上 是我对这道算法的一些遐想和延伸, 可能不是最优解, 但是算法的优化嘛 本身就是一个思索的过程, 能在这个思索和迭代的过程中有所收获和乐趣就是在成长了, 欢迎大家一起来交流更多的解答...