92_反转链表II
package 链表; import 二叉树.二叉搜索树.TreeNode; /** * https://leetcode-cn.com/problems/reverse-linked-list-ii/ * @author Huangyujun * *思路: 断链前一个的指针 (pre) *片段的最后一个结点: fragLast *断链后的第一个指针(post) */ public class _92_反转链表II { public ListNode reverseBetween(ListNode head, int left, int right) { // 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论 ListNode dummyNode = new ListNode(-1); dummyNode.next = head; ListNode pre = dummyNode; // 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点 // 建议写在 for 循环里,语义清晰 for (int i = 0; i < left - 1; i++) { pre = pre.next; } // 第 2 步:从 pre 再走 right - left + 1 步,来到 post 节点 ListNode fragLast = pre; for (int i = 0; i < right - left + 1; i++) { fragLast = fragLast.next; } // 第 3 步:切断出一个子链表(截取链表) ListNode fragFirst = pre.next; ListNode post = fragLast.next; // 注意:切断链接 pre.next = null; fragLast.next = null; // 第 4 步:同第 206 题,反转链表的子区间 reverseLinkedList(fragFirst); // 第 5 步:接回到原来的链表中 pre.next = fragLast; fragFirst.next = post; return dummyNode.next; } private void reverseLinkedList(ListNode head) { // 也可以使用递归反转一个链表 ListNode pre = null; ListNode cur = head; while (cur != null) { ListNode next = cur.next; cur.next = pre; pre = cur; cur = next; } } }