美文网首页@IT·互联网
Leetcode92:反转链表II(区间反转链表)

Leetcode92:反转链表II(区间反转链表)

作者: 我可能是个假开发 | 来源:发表于2024-02-02 22:45 被阅读0次

    一、题目

    给你单链表的头指针 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]
    

    left和right是索引,但是是从1开始(很无语,,,害我写了好多次才通过)

    二、题解

    思路:先找到left节点,再计算left到right中间的次数(就是要循环的次数),用3个指针:

    • preHead:指向left索引的上一位(他的next用来连接要插入到left头的节点)
    • pre:指向left索引
    • cur:指向left索引的下一位(要把cur插入到头部(即PreHead.next)去)

    每次让left后面的节点(cur指针指向的元素)插入到left前面(preHead指针的位置)。即头插法(可以看我上一篇文章的反转链表的第一种解法,只是这里不创建新的节点,而是直接改变前后节点的指针;头插法就是依次把后面的元素插入到第一位去,一直到right结束,那么当前区间的链表就逆序了)

    比如head = [1,2,3,4,5], left = 2, right = 4:

    • 3(cur指针指向的节点) 插入到2(pre指针指向的节点)的前面; [1,3,2,4,5]
    • cur指针往后移动
    • 4(cur指针指向的节点)插入到3(pre指针指向的节点)的前面: [1,4,3,2,5]

    为了方便操作,设置一个虚拟头节点:
    因为按照3个指针的写法,left位置前面是有一个节点的,但是如果要逆序的就是第一个和第二个,如果没有头节点,preHead就不存在了,就又要特殊处理。所以设置一个虚拟头节点让left不管是第一位还是第n位,都能走同样的逻辑。
    第一遍:


    第一遍.png

    第二遍:


    第二遍.png
    class Solution {
    
        public ListNode reverseBetween(ListNode head, int left, int right) {
            if (left == right) {
                return head;
            }
            //创建一个虚拟头节点指向一开始的头节点
            ListNode dummy = new ListNode(-1,head);
    
            left = left - 1;
            right = right - 1;
    
            //要开始反转的节点的前一个节点
            ListNode preHead;
            head = dummy;
            //找到要翻转的起点 1->2->3->4->5->6
            //1->2->3->4->5->6 (2,4)
            for (int i = 0; i < left; i++) {
                head = head.next;
            }
            preHead = head;
            //反转的起点
            ListNode pre = preHead.next;
            // 要移动的节点
            ListNode cur = preHead.next.next;
    
            if (cur == null) {
                //链表只有两个节点 直接交换两个节点返回
                ListNode next = preHead.next;
                preHead.next = null;
                next.next = preHead;
                return next;
            }
    
            //要翻转的次数
            for (int j = 0; j < right-left; j++) {
                 //暂存
                ListNode newHead = preHead.next;
                //暂存
                ListNode nextCur = cur.next; 
    
                pre.next = nextCur;
                preHead.next = cur;
                cur.next = newHead;
    
                //指针往前移动
                cur = nextCur;
            }
            return dummy.next;
        }
    }
    class ListNode {
        int val;
        ListNode next;
    
        ListNode() {
        }
    
        ListNode(int val) {
            this.val = val;
        }
    
        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    
        @Override
        public String toString() {
            return "ListNode{" +
                    "val=" + val +
                    ", next=" + next +
                    '}';
        }
    }
    

    相关文章

      网友评论

        本文标题:Leetcode92:反转链表II(区间反转链表)

        本文链接:https://www.haomeiwen.com/subject/omytadtx.html