力扣第九十二题-反转链表 II

471 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

前言

力扣第九十二题 反转链表 II 如下所示:

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:

输入: head = [1,2,3,4,5], left = 2, right = 4
输出: [1,4,3,2,5]

示例 2:

输入: head = [5], left = 1, right = 1
输出: [5]

一、思路

这一题题目意思还是比较清楚的,就是反转链表中的 left ~ right 位置的元素

像这种链表相关的题目,我们不用着急去写代码,可以先画一个图,明确子集需要哪些东西。

这一题既然要反转,我们至少需要知道这以下这四个信息:

这里以 head = [1,2,3,4,5], left = 2, right = 4 作为例子

  1. leftHead:指向链表中的前面还未反转的节点。(此处 leftHead 需要指向第一个节点 1
  2. rightHead:指向链表中后面未反转的节点。(此处指向最后一个未反转的节点 5
  3. newLeftHead:指向反转位置的第一个元素。(因为是反转的第一个元素,所以这里指向倒数第二个元素 4
  4. newRightHead:指向反转位置的最后一个元素。(同理,因为需要反转,所以这里指向第二个元素 2

这四个指针具体如下图所示:

因为单纯的反转链表,我们只需要将添加的元素放到链表的最前面即可。所以我们分析时,可以暂时忽略反转 left ~ right 位置的节点

image.png

如上图所示,我们有了这四个指针后就非常好操作了。只需合并指针指向的结果即可。

  1. newRightHead.next = rightHead
  2. leftHead.next = newLeftHead.next

那如何找到这四个指针呢?只需要通过以下几个步骤即可:

  1. 遍历链表并计数,count 表示当前节点的位置,next 表示当前节点
  2. count < left:更新 leftHead = next
  3. count == left:更新 newRightHead,因为第一个添加的元素在结果中是在最右边的
  4. count > rightrightHead = next 指向右边第一个未反转的元素即可

二、实现

实现代码

实现代码与思路中保持一致

    public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode newLeftHead = new ListNode();
        ListNode newRightHead = newLeftHead;
        ListNode leftHead = null;
        ListNode rightHead = null;
        ListNode next = head;
        int count = 1;
        while (next != null) {
            if (count < left) { // left指向反转前的节点
                leftHead = next;
            } else if (count >= left && count <= right) {
                ListNode temp =new ListNode(next.val);
                temp.next = newLeftHead.next;
                newLeftHead.next = temp;
                if (count == left) {
                    newRightHead = newRightHead.next;   // right指向第一个添加的节点
                }
            }
            if (count > right){
                rightHead = next;
                break;
            }
            next = next.next;
            count++;
        }
        newRightHead.next = rightHead;
        if (leftHead == null) { // 说明原链表中开始处没有元素了
            return newLeftHead.next;
        }else {
            leftHead.next = newLeftHead.next;
            return head;
        }
    }

测试代码

    public static void main(String[] args) {
        ListNode listNode = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5 )))));
        ListNode listNode1 = new ListNode(5);
        new Number92().reverseBetween(listNode, 2, 4);
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~