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

97 阅读1分钟

链表指定区间反转

图片.png

1.头插法

思路:在反转的区间内,每次遍历到一个新的节点,都把它接入到反转起点(left位置)。 图片.png

public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode dummy = new ListNode(-1,head);
        ListNode pre = dummy;
        ListNode next = null;
        for(int i=0;i<left-1;i++){
            pre = pre.next;
        }
        ListNode cur = pre.next;
        for(int i=0;i<right-left;i++){
            next = cur.next;
            cur.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }
        return dummy.next;
    }
    

2.穿针引线法

思路:将反转区间的前节点(pre)和后节点(succ)存起来,直到反转区间反转完成,再接入反转链表即可。

图片.png

public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode dummy = new ListNode(-1,head);
        ListNode pre = dummy;
        for(int i=0;i<left-1;i++){
            pre = pre.next;
        }
        ListNode rightNode = pre;
        for(int i=0;i<right-left+1;i++){
            rightNode = rightNode.next;
        }
        ListNode succ = rightNode.next;
        ListNode leftNode = pre.next;
        rightNode.next = null;//防止成环

        reverseLinkedList(leftNode);    
        pre.next = rightNode;//此时链表反转完成,左右节点位置互换
        leftNode.next = succ;
        return dummy.next;
    }
     private void reverseLinkedList(ListNode head) {//反转链表
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
     }