2021.3.18
https://leetcode-cn.com/problems/reverse-linked-list-ii/
题目
给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

输入:head = [1,2,3,4,5], left = 2, right = 4输出:[1,4,3,2,5]输入:head = [5], left = 1, right = 1输出:[5]
提示:
- 链表中节点数目为
n 1 <= n <= 500-500 <= Node.val <= 500-
思路
一趟扫描完成。防止从第一个节点开始翻转的特殊情况,建立哨兵节点(给head节点加一个父亲father)。
- 然后找到left位置的节点,将left位置节点的父亲记录下来,开始寻找right。
- 将left到right看作一条单独的链,left是链尾tail,right是链头head2,开始链尾链头都是left位置的节点。
- 然后遍历下一个节点t,将其加入单独链中,此时该节点为链头,它的next指向之前的链头。
- 如果该节点的位置正好是right,则单独链的翻转已经完成,将其加入整条链中,单独链的链尾的next指向right位置节点的next,父亲节点的next指向right位置节点,链表反转完成。
- 此时新链的head为哨兵节点的next值。
AC代码
/*** 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户* 内存消耗:35.9 MB, 在所有 Java 提交中击败了83.90%的用户*/public ListNode reverseBetween(ListNode head, int left, int right) {// 位置相等不用翻转直接返回head节点if (left == right) {return head;}// 建立哨兵节点ListNode sentry = new ListNode(0, head);// 寻找left位置的节点ListNode leftNode = sentry;ListNode father = null;int count = 0;while (leftNode.next != null) {ListNode node = leftNode.next;count++;if (count == left) {// 记录left位置节点的父亲father = leftNode;leftNode = node;break;}leftNode = node;}// 翻转left-right之间的链表ListNode tail = leftNode, head2 = leftNode, node = leftNode.next;while (node != null) {count++;// 找到right位置if (count == right) {ListNode next = node.next;node.next = head2;tail.next = next;father.next = node;break;}ListNode next = node.next;node.next = head2;head2 = node;node = next;}// 返回哨兵节点的next,为新链的链头return sentry.next;}
