递归反转整个链表
// 定义:输入一个单链表头结点,将该链表反转,返回新的头结点
ListNode reverse(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode last = reverse(head.next);
head.next.next = head;
head.next = null;
return last;
}
输入 reverse(head)
后,会在这里进行递归
这个 reverse(head.next)
执行完成后,整个链表就成了这样:
head.next.next = head;
head.next = null;
return last;
当链表递归反转之后,新的头结点是 last
,而之前的 head
变成了最后一个节点,别忘了链表的末尾要指向 null:
反转前N个节点
ListNode successor = null; // 后驱节点 存放第N+1节点
ListNode reverseN(ListNode head, int n) {
if(n==1){
successor = hean.next;
}
ListNode last = reverseN(successor.next, n - 1);
head.next.next = head;
head.next = successor;
return last;
}
1、base case 变为 n == 1
,反转一个元素,就是它本身,同时要记录后驱节点。
2、刚才我们直接把 head.next
设置为 null,因为整个链表反转后原来的 head
变成了整个链表的最后一个节点。但现在 head
节点在递归反转之后不一定是最后一个节点了,所以要记录后驱 successor
(第 n + 1
个节点),反转之后将 head
连接上。