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

文章介绍了如何对链表的指定区间进行反转,提供了两种方法:1.头插法,通过移动节点使其直接到达反转开始位置来避免二次遍历;2.穿针引线法,将链表分为三部分,反转中间部分后再连接。这两种方法都实现了在O(n)时间复杂度内完成反转。
摘要由CSDN通过智能技术生成

上回了解了链表的反转,接下来深入了解下链表指定区间的反转。

指定区间反转比链表的反转稍微难一点,但也差不多,这里采用2种方法解决,1.头插法 2.穿针引线法。

1.头插法

头插法的缺点是如果left和right的区间间隔很大,找到left和right需要遍历依次,反转还要再遍历依次。虽然时间复杂度为O(n),但是可以只遍历一遍吗?答案是肯定的。

只需要在反转的区间内,每遍历一个节点,就让这个节点到反转部分的开始位置。

 

实现代码:

 

public static Node invertListBetweenNode(Node node,int left,int right){
        Node dummyNode = new Node();
        dummyNode.next = node;
        Node res = dummyNode;
        for (int i = 0; i < left - 1; i++){
            res = res.next;
        }
        Node cur = res.next;//开始反转节点的位置
        Node next;//下一个要反转节点
        for (int i = 0; i < right - left; i++){
            next = cur.next;//反转节点位置为要反转节点位置
            cur.next = next.next;//
            next.next = res.next;//指向开始反转的节点
            res.next = next;//指向开始
        }
        return dummyNode.next;
    }

2.穿针引线法

这种方式同样适用于之前的链表反转方式,确定需要反转的部分,然后将三个链表连接起来,第一部分是left前的部分,第二部分是left到right之间的部分,第三部分是right后的部分。

 实现代码:

    public static Node invertListBetweenNode2(Node node,int left, int right){
        Node dummyNode = new Node();
        dummyNode.next = node;
        Node res = dummyNode;
        //第一部分
        for (int i = 0; i < left - 1; i++){
            res = res.next;
        }
        //第二部分
        Node rightNode = res;
        for (int i = 0; i < right -left + 1; i++){
            rightNode = rightNode.next;
        }
        Node leftNode = res.next;
        //第三部分
        Node end = rightNode.next;
        rightNode.next = null;//把反转区间的链表最后一个节点的下一个指向null
        //反转leftNode链表;
        invertLinkedList(leftNode);
        //三部分链表结合
        res.next = rightNode;
        leftNode.next = end;

        return dummyNode.next;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值