92.链表翻转
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
编码准备:一个单链表
ListNode head = new ListNode(1);
ListNode start = head;
int count =2;
while (head.next == null && count < 7) {
head.next = new ListNode(count);
head = head.next;
count++;
}
准备知识:
1、递归的反转链表
不清楚点: 递归直接返回尾节点。
完整过程分析之后、递归过程只是层层深入,寻找尾节点。到底层之后,对链表方向进行转换,但是没有改变尾节点。
因此:
ListNode last = reverse(head.next);
顶层能直接获取到尾节点,接下来便是对链表的方向转变
// base case
if (null == head.next) {
return head;
}
ListNode last = reverse(head.next);
head.next.next = head;
head.next = null;
return last;
任取一过程
2、反转前k个链表节点
同理,唯一的区别是:需要保存一个k+1个节点,链接反转部分与原部分。
static ListNode after = null;
public static ListNode reverseN(ListNode head, int n) {
// base case
if (n == 1) {
after = head.next;
return head;
}
ListNode last = reverseN(head.next, n - 1);
head.next.next = head;
head.next=after;
return last;
}
运行时截图:
一直把尾部与被反转部分相连接
3、反转制定索引区间的链表
同理:指定区间与前k个链接区别在于开始位置的不同,因此可以递归的找到开始位置,之后同样的逆转前k个节点。
public static ListNode reverseAToB(ListNode head, int a, int b) {
if (a==1) {
// base case
return reverseN(head,b);
}
// 获得逆序[a,b]后的节点b
ListNode last = reverseAToB(head.next, a - 1, b - 1);
ListNode temp = last;
// 链接原串
head.next = last;
return head;
}
运行时输出