天天看點

LeetCode 143. Reorder List(重組連結清單)

原題網址:https://leetcode.com/problems/reorder-list/

Given a singly linked list L: L0→L1→…→Ln-1→Ln,

reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

For example,

Given 

{1,2,3,4}

, reorder it to 

{1,4,2,3}

.

方法一:使用棧來反轉。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void reorderList(ListNode head) {
        if (head == null) return ;
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }

        Stack<ListNode> stack = new Stack<>();
        ListNode half = slow.next;
        while (half != null) {
            stack.push(half);
            half = half.next;
        }
        slow.next = null;
        
        ListNode current = head;
        while (current != null && !stack.isEmpty()) {
            ListNode next = current.next;
            current.next = stack.pop();
            current.next.next = next;
            current = next;
        }
    }
}
           

方法二:分三步,先找中間點,再反轉後半部分,然後合并。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    private ListNode reverse(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode previous = head;
        ListNode current = head.next;
        head.next = null;
        ListNode reversed = null;
        do {
            reversed = current;
            ListNode next = current.next;
            current.next = previous;
            previous = current;
            current = next;
        } while (current != null);
        return reversed;
    }
    public void reorderList(ListNode head) {
        if (head == null) return ;
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }

        ListNode half = reverse(slow.next);
        slow.next = null;
        
        ListNode current = head;
        while (current != null && half != null) {
            ListNode cnext = current.next;
            ListNode hnext = half.next;
            current.next = half;
            half.next = cnext;
            current = cnext;
            half = hnext;
        }
    }
}
           

另一種實作:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void reorderList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) return;
        ListNode former = head;
        ListNode formerCurrent = former;
        
        ListNode slow = head;
        ListNode fast = head.next;
        while (fast != null && fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        
        ListNode latter = slow.next;
        slow.next = null;
        ListNode latterCurrent = latter.next;
        latter.next = null;
        while (latterCurrent != null) {
            ListNode next = latterCurrent.next;
            latterCurrent.next = latter;
            latter = latterCurrent;
            latterCurrent = next;
        }
        
        latterCurrent = latter;
        while (formerCurrent != null && latterCurrent != null) {
            ListNode formerNext = formerCurrent.next;
            ListNode latterNext = latterCurrent.next;
            formerCurrent.next = latterCurrent;
            if (formerNext != null) latterCurrent.next = formerNext;
            formerCurrent = formerNext;
            latterCurrent = latterNext;
        }
    }
}