[LeetCode] - Reorder List

Given a singly linked list LL0L1→…→Ln-1Ln,
reorder it to: L0LnL1Ln-1L2Ln-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}.


這道題像是一道鏈表的綜合題,因爲解題過程中需要用到很多鏈表的常用操作,比如快慢指針取中點,翻轉鏈表等等。我覺得最好把其中的每個步驟都寫成了一個函數,這樣清楚明瞭。

具體的思路如下:

1. 拆分。用快慢指針找到鏈表的中點,然後將鏈表一分爲二。初始條件應該設置爲,slow=head, fast=head.next,然後進入while循環。這樣出來的結果可以保證:(1)如果鏈表長度爲偶數,則前半部分的長度和後半部分相等;(2)如果鏈表長度爲奇數,則前半部分的長度比後半部分大1。這樣的結果方便後面的insert。

2. 反轉。對拆分之後的後半部分進行反轉。鏈表反轉的算法很常用了,就是加入一個fake,然後把head後面的每個node一個個的插入到fake和fake.next之間就可以了。

3. 插入。將反轉之後的後半部分鏈表插入到前半部分之中。


代碼如下:

/**
 * 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) {
        if(head==null || head.next==null) return;
        ListNode second = cut(head);
        second = reverse(second);
        insert(head, second);
        return;
    }
    
    public ListNode cut(ListNode head) {
        ListNode slow=head, fast=head.next;
        
        // odd->fast==null; even->fast.next==null
        // guarantee that the length of 1st half is equal or longer than the 2nd half
        while(fast!=null && fast.next!=null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode secHead = slow.next;
        slow.next = null;
        return secHead;
    }
    
    public ListNode reverse(ListNode head) {
        ListNode fake = new ListNode(-1);
        fake.next = head;
        ListNode cur = head.next;
        while(cur != null) {
            head.next = cur.next;
            cur.next = fake.next;
            fake.next = cur;
            cur = head.next;
        }
        return fake.next;
    }
    
    public void insert(ListNode first, ListNode second) {
        while(second != null) {
            ListNode temp = second.next;
            second.next = first.next;
            first.next = second;
            first = first.next.next;
            second = temp;
        }
        return;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章