算法修煉之路——【鏈表】Leetcode 328 奇偶鏈表

題目描述

給定一個單鏈表,把所有的奇數節點和偶數節點分別排在一起。請注意,這裏的奇數節點和偶數節點指的是節點編號的奇偶性,而不是節點的值的奇偶性。

請嘗試使用原地算法完成。你的算法的空間複雜度應爲O(1),時間複雜度應爲O(nodes)nodes爲節點總數。

示例1:

輸入: head = [1, 2, 3, 4, 5]
輸出: [1, 3, 5, 2, 4]

示例2:

輸入: head = [2, 1, 3, 5, 6, 4, 7]
輸出: [2, 3, 6, 7, 1, 5, 4]

說明:

  • 應保持奇數節點和偶數節點的相對順序;
  • 鏈表的第一個節點視爲奇數節點,第二個節點視爲偶數節點,以此類推;

思路分析

我們通過簡單的思考,可以想出通過對鏈表進行“奇數分區”和“偶數分區”進行節點區分,此時我們不免會想到,奇數分區需要一個指針指向奇數分區尾節點oddTail以便後續節點的插入;同樣地, 偶數分區也需要一個指針指向偶數分區尾節點evenTail;同時,我們遍歷還需要一個遍歷指針p

此時我們對遍歷、插入的準備工作進行了簡單討論,這裏我們通過代碼實現時,會發現我們需要對p遍歷時對節點的 “奇偶性”進行判斷 ,因爲這裏是下標的奇偶性,故我們可以通過設置一個布爾常量來進行標識。

再進一步思考,因爲鏈表之被分爲兩個分區,在代碼運行過程中鏈表一般可被表示爲三個區域:a. 偶數分區;b. 奇數分區;c. 待遍歷分區。如圖1所示:

在這裏插入圖片描述
圖1

這裏我們可以看到,在p遍歷的時候,會已知保持與指針evenTail的前後關係,則我們這裏去掉p指針,則現在我們需要的就是兩個分區指針oddTail, evenTail和一個布爾變量進行功能實現。這裏我們直接給出解題步驟與解題代碼:

解題步驟

  1. 初始化兩個分區指針oddTail, evenTail和布爾變量isOddNode
  2. 遍歷原始鏈表,根據isOddNode判斷evenTail.next是否插入奇數分區;
  3. evenTail.next == null時停止並返回head.

解題代碼

    public static ListNode solution(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) {
            return head;
        }

        /* Step1: Init. pointers */
        ListNode oddTail = head;
        ListNode evenTail = head.next;
        
        boolean isOddNode = true;
        /* Step2: go through the head-list
        and
        split nodes according the odevity(奇偶性) of index
         */
        while(evenTail.next != null){
            ListNode node = evenTail.next;
            
            // oddNode: directly insert after oddTail
            if(isOddNode){
                evenTail.next = evenTail.next.next;
                node.next = oddTail.next;
                oddTail.next = node;
                
                oddTail = node;
                isOddNode = false;
            }else{ // evenNode: just move forward
                evenTail = evenTail.next;
                isOddNode = true;
            }
            
        }
        /* Step3: return head */
        return head;
    }

複雜度分析

時間複雜度:我們對原始鏈表進行了一次遍歷,容易理解時間複雜度爲O(N);
空間複雜度:我們這裏沒有設置輔助容器,只需要兩個指針和一個布爾量,故空間複雜度爲O(1).

GitHub源碼

完整可運行文件請訪問GitHub

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