算法通关村第二关——指定区间链表反转问题解析

今天分享两种方法:

        1.头插法

        2.穿针引线法

1、头插法

        顾名思义,就是遍历区间内的节点,然后依次插在区间左节点的前一个节点后边。

//区间内链表反转
    //方法1;头插法
    private static ListNode reverseBetween1(ListNode head, int left, int right) {
        ListNode ans = new ListNode(-1);
        ans.next = head;
        ListNode pre = ans;     //pre指向虚拟头结点
        //pre向前走i步,到达区间左节点的前一个节点停下,方便区间节点的插入
        for (int i = 0; i < left - 1; i++) {
            pre = pre.next;
        }
        ListNode cur = pre.next;    //用cur结点标记pre的下一个结点,及区间的左节点,替代pre继续向后遍历
        for (int i = 0; i < right - left; i++) {    //继续向后遍历right-left个节点,
                                            // 目的是将区间内的所有节点都插入到pre的后边
            ListNode next = cur.next;
            cur.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }
        return ans.next;
    }

 2、穿针引线法

        第一步:根据区间结点,将原始链表分为三部分(即头链表,区间链表,尾链表)。

        第二步:将区间结点部分进行链表翻转

        第三步:按顺序(头链表,反转后的区间链表,为链表)连接,最后返回ans.next。

ans是虚拟头结点。


代码中有详细的解释,方便理解

//方法2:穿针引线法
    private static ListNode reverseBetween2(ListNode head, int left, int right) {
        ListNode ans = new ListNode(-1);
        ans.next = head;
        ListNode pre = ans;
        //pre走left-1步,走到left节点的前一个结点
        for (int i = 0; i < left - 1; i++) {
            pre = pre.next;
        }
        //标记  pre是left前一个节点,同时又是第一个链表的尾结点
        //      这么写的目的是:防止pre节点的丢失,用firstLast来代替pre继续遍历
        ListNode firstLast = pre;
        //firstLast走到right节点
        for (int i = 0; i < right - left + 1; i++) {
            firstLast = firstLast.next;
        }
        //经过for循环后firstLast指向区间链表的尾结点

        //newLinkedList指向区间链表的头节点,加上 firstLast.next=null; 这行代码,使其表示区间链表
        ListNode newLinkedList = pre.next;
        //lastLinkedList是第三部分代码,及区间链表后边的链表。这么定义方便后边的链表重组
        ListNode lastLinkedList = firstLast.next;
        firstLast.next=null;
        //反转区间链表
        reverseList(newLinkedList);

        pre.next=firstLast;
        newLinkedList.next=lastLinkedList;
        
        return ans.next;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值