剑指 Offer 24. 反转链表
pre
指向上一个节点,初始值为null
,然后遍历链表,一边遍历一遍交换指针指向:
nextNode
下下一个节点cur
指向pre
pre
指向cur
cur
指向nextNode
即可完成两个节点的反转class Solution { public ListNode reverseList(ListNode head) { // 保证链表的元素大于1个时才反转 if (head == null || head.next == null) { return head; } // 常见pre指针,存储上一个节点,要指向null,因为要保证第一个元素的next能指向null // 反转过程是这样的:首先存储当前节点的下一个节点nextNode,然后将当前元素的next指向pre,最后将pre指向head、head指向nextNode即可 ListNode pre = null; while (head != null) { ListNode nextNode = head.next; head.next = pre; pre = head; head = nextNode; } // 此时head指向的是null,pre指向的是反转后的头节点 return pre; } }
当前节点的下一个节点的next指针
指向当前节点
,即cur.next.next = cur
,然后将当前节点cur
的指针指向null
(如果不指向null
的话会导致反转后的最后一个节点不是指向null
,因此形成环),每一层递归都这样子做,最后就可以将链表反转了cur
的next
指向null
class Solution { public ListNode reverseList(ListNode head) { // 只有链表节点个数大于1个时候才需要反转 if (head == null || head.next == null) { return head; } // 反转链表 return dfs(head); } public ListNode dfs(ListNode node) { // 遍历到最后一个节点的时候开始返回 if (node.next == null) { return node; } // 获取链表的最后一个节点,也是将来的反转之后的头节点 ListNode last = dfs(node.next); // 进行链表指针的指向的修改 // 将下一个节点的next指向当前节点 node.next.next = node; // 将当前节点指向null // 如果这个不设置null的话,最后一个节点就不能指向null了,导致存在环形链表 node.next = null; return last; } }