链表内指定区间反转

将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转;

    public ListNode reverseBetween(ListNode head, int m, int n) {
        // 1 >> 2 >> 3 >> 4 >> 5 >> 6 >> 7 >> 8 假设反转 3~6
        // 1 >> 2 >> 6 >> 5 >> 4 >> 3 >> 7 >> 8
        /**
         * 这个里面有几个关键点
         * 找到元素2 到2之前的元素都不会发生变更 pre
         * 找到元素7 到7之后的元素都不会发生变更 right
         * 找到元素3 从该元素开始反转 start
         * 找到元素6 从该元素结束反转 end
         * start ~ end 之间的元素进行反转
         * 如上图链表反转之后 2->6 即 pre.next - end ,3->7 即 start.next - right
         */
        ListNode res = new ListNode(0);
        res.next = head ;
        ListNode pre = res;
        for (int i = 0; i < m-1; i++) {
            pre = pre.next ;
        }

        ListNode start = pre.next ;
        ListNode end = start ;
        for (int i = 0; i < n-m; i++) {
            end = end.next ;
        }
        ListNode right = end.next ;
        end.next = null ;
        // 区间反转
        reverseNode(start);
        pre.next = end ;
        start.next = right ;
        return res.next ;

    }


    private void reverseNode(ListNode node) {
        if(node == null || node.next ==null){
            return;
        }
        Stack<ListNode> stack = new Stack<>();
        while (node!=null){
            stack.add(node);
            node = node.next;
        }
        ListNode res = stack.pop();
        while (!stack.isEmpty()){
            res.next = stack.pop();
            res = res.next ;
        }
    }

    class ListNode {
        int val;
        ListNode next = null;

        public ListNode(int val) {
            this.val = val;
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值