https://oj.leetcode.com/problems/reorder-list/

http://blog.csdn.net/linhuanmars/article/details/21503215

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public void reorderList(ListNode head) {
        
        // Solution A:
        reorderList_NoExtraSpace(head);
        
        // Solution B:
        // reorderList_Map(head);
    }


    //////////////////////////
    // Solution A: NoExtraSpace
    //
    public void reorderList_NoExtraSpace(ListNode head)
    {
        // Hit to the middle
        //
        // Iterate list with 2 pointers.
        // p1 with 1 pace
        // p2 with 2 paces.
        // Thus, when p2 reach end.
        // p1 = size / 2 (odd)
        //    = (size / 2) - 1 (even)
        
        if (head == null || head.next == null)
            return;
            
        ListNode p1 = head;
        ListNode p2 = head;
        ListNode lastp1 = null;
        while (p1 != null && p2 != null)
        {
        	lastp1 = p1;
            p1 = p1.next;
            p2 = p2.next;
            if (p2 == null)
                p2 = null;
            else
                p2 = p2.next;
        }
        p2 = p1; //.next;
        lastp1.next = null;
        p1 = head;// 0, 1, 2, ...
        p2 = reverse(p2); // n-1, n-2, n-3, ...
        
        // Merge head & p1
        while (p1 != null)
        {
            ListNode p1next = p1.next;
            p1.next = p2;
            ListNode p2next = null;
            if (p2 != null)
            {
                p2next = p2.next;    
                p2.next = p1next;
                p2 = p2next;
            }
            p1 = p1next;
        }
    }
    
    private ListNode reverse(ListNode head)
    {
        ListNode tail = head;

        if (tail == null)
            return tail;

        ListNode temp = head.next;
        while (temp != null)
        {
            // Move tail to head.
            // Temp tail.pre become new tail. 
            // go next
            
            ListNode next = temp.next;
            tail.next = next;
            temp.next = head;
            head = temp;
            temp = next;
        }
        return head;
    }
    

    //////////////////////////
    // Solution A: Map
    //    
    // or using stack might be better
    public void reorderList_Map(ListNode head) 
    {
        if (head == null)
            return;
            
        Map<Integer, ListNode> map = new HashMap<>();
        
        int size = 0;
        ListNode temp = head;
        while (temp != null)
        {
            map.put(size, temp);
            size++;
            temp = temp.next;
        }
        
        // Restruct
        ListNode lastNode = null;
        for (int i = 0 ; i < size ; i ++)
        {
            ListNode curNode = null;
            if (i % 2 == 0)
            {
                curNode = map.get(i / 2);
            }
            else
            {
                curNode = map.get(size - 1 - i / 2);
            }
            if (lastNode != null)
                lastNode.next = curNode;
            curNode.next = null;
            lastNode = curNode;
        }
    }
}