题目描述

// 92. 反转链表 II
// 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。
// 请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
题解
// 本题可以借鉴【Leetcode】206. 反转链表 的方法。
// 假设left所在结点为leftHead,right所在结点为r,
// 我们需要找leftHead的前一个结点l,和r的后一个结点 rightTail,把
// leftHead和l断开连接,把r和rightTail断开连接,然后将中间从leftHead到
// r这段需要反转的链表用【Leetcode】206. 反转链表 方法进行翻转,
// 然后再把头尾接上即可。
//
// 首先head前面设一个虚拟头结点dummyHead,令l结点从dummyHead开始遍历,
// 因为left表示的是索引下标,而且是从1(一)开始计数的,而l指针是从head
// 前面的dummyHead开始计数的,所以相当于从0开始往上数,遍历到left-1之前即可
// 因为我们要的是left的前一个结点。
// 而r同理,r需要正好遍历到right结点,先将r初始化到此时的l位置,
// 然后从l开始遍历到right位置,就是从0遍历到right-left+1之前即可。
// 这样我们就得到了left的前一个位置l,和right位置的r结点。
// 我们真正要反转的区域就是l.next到r这个区域,令leftHead = l.next,
// 再取r的下一个结点为rightTail。
//
// 之后我们将需要反转区域和链表切断连接,定义reverse函数,代码跟206.基本一样
// 不过我们这里不用返回什么东西。
//
// 反转之后,被反转区域的链表,原来的链表头leftHead会变成链表尾,
// 原来的链表尾r会变成链表头,让l.next与链表头r连接,
// 让链表尾leftHead与rightTail连接。最后返回整个大链表的头dummyHead.next
// 完成。
//
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:35.8 MB, 在所有 Java 提交中击败了92.49%的用户
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
if (left == right)
return head
ListNode dummyHead = new ListNode(-1)
dummyHead.next = head
ListNode l = dummyHead
for (int i = 0
l = l.next
}
ListNode r = l
for (int i = 0
r = r.next
}
ListNode leftHead = l.next
ListNode rightTail = r.next
l.next = null
r.next = null
reverse(leftHead)
l.next = r
leftHead.next = rightTail
return dummyHead.next
}
public void reverse(ListNode head) {
if (head == null || head.next == null)
return
ListNode pre = head
ListNode mid = head.next
ListNode cur = head.next.next
mid.next = pre
while (cur != null) {
pre = mid
mid = cur
cur = cur.next
mid.next = pre
}
}
}