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}.

给定一个链表让我们重新排列它,例如以前的顺序为0-1-2-3-4,排列后的顺序为0-4-1-3-2。我们首先要找到中间的节点,用快慢指针,这个比较简单,不过值得注意的是节点是奇数和偶数的不同情况。找到中间节点后我们可以借助堆栈将后半部分的节点压栈,然后从头结点开始一个一个的处理,可以解决。堆栈实际上帮我们将链表的后半段反转了,如果我们不借助堆栈也可以解决,我们可以将链表从中间节点分为两段,将后半段反转,然后再将两个链表合为一个链表,这样就不需要借助堆栈,时间复杂度为O(n), 空间复杂度为O(1)。下面是两种方法的代码:
1,Using stack
/**
 * 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) {
        Stack stack = new Stack();
        if(head == null) return;
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
       
        if(fast != null){
            slow = slow.next;
        }
        while(slow != null) {
            stack.push(slow);
            slow = slow.next;
        }
        while(!stack.isEmpty()){
            ListNode top = stack.pop();
            ListNode temp = head.next;
            head.next = top;
            top.next = temp;
            head = temp;
            
        }
        head.next = null;
    }
}


2,Without stack
/**
 * 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) return;
        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = null;
        //get the middle node, and cut list into two sublists
        while(fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode midNode = slow.next;
        slow.next = null;
        
        // reverse the latter part
        ListNode newNode = reverseLatterPart(midNode);
        
        //merge two sublists
        while(newNode != null) {
            ListNode tem = head.next;
            head.next = newNode;
            head = newNode;
            newNode = tem;
        }
        
    }
    private ListNode reverseLatterPart(ListNode head) {
        ListNode prev = null;
        ListNode tem = null;
        while(head != null) {
            tem = head.next;
            head.next = prev;
            prev = head;
            head = tem;
        }
        return prev;
    }
    
}

你可能感兴趣的:(链表,反转)