利用虚拟头结点
第一种方法是新建一个节点 dummy(虚拟节点),在遍历要翻转的链表,把遍历出来的节点依次插入新建点 dummy 的表头;最后再返回 dummy 的 next 就好了;
public ListNode reverseList(ListNode head) {
ListNode dummy = new ListNode(-1);
ListNode cur = head;
ListNode curNext;
while(cur != null) {
// 保存当前节点的 下一个节点,不然会丢失
curNext = cur.next;
// 当前节点的 next 指向 dummy 的next,也就是新链表的链表头
cur.next = dummy.next;
// dummy 的下一个指向当前节点
dummy.next = cur;
// 当前节点继续向前遍历
cur = curNext;
}
return dummy.next;
}
直接操作链表实现反转
那么如何不借助于其他新的虚拟节点,直接在当前节点进行翻转
需要遍历链表,再记录当前节点 cur 的前一个节点 pre 和后一个节点 next;把 cur 的next 指向 pre,在讲 pre 指向 next,最后再把当前节点向后移动既可
public ListNode reverseList(ListNode head) {
ListNode preHead = null;
ListNode cur = head;
ListNode curNext = null;
while(cur != null) {
curNext = cur.next;
cur.next = preHead;
preHead = cur;
cur = curNext;
}
return preHead;
}
递归
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode last = reverseList(head.next);
head.next.next = head;
head.next = null;
return last;
}