奇偶鏈表問題

奇偶鏈表問題

作者:Grey

原文地址:

博客園:奇偶鏈表問題

CSDN:奇偶鏈表問題

題目描述

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

請嘗試使用原地算法完成。

你的算法的空間複雜度應爲 O(1),

時間複雜度應爲 O(nodes),nodes 爲節點總數。

示例 1:

輸入: 1->2->3->4->5->NULL

輸出: 1->3->5->2->4->NULL

示例 2:

輸入: 2->1->3->5->6->4->7->NULL

輸出: 2->3->6->7->1->5->4->NULL

說明: 應當保持奇數節點和偶數節點的相對順序。

鏈表的第一個節點視爲奇數節點,第二個節點視爲偶數節點,以此類推。

題目鏈接

主要思路

如果用輔助數組來做,非常簡單,但是不滿足題目的要求,因爲題目要求空間複雜度 O(1),意味着不能額外申請輔助數組,換一個思路,考慮用一個整型變量來記錄遍歷的位置是奇數還是偶數,然後用四個指針分別記錄當前奇數鏈表的開頭,結尾;偶數鏈表的開頭和結尾,最後把兩個鏈表串聯起來即可,所以,只需要設置五個變量即可完成整個算法。

// 奇數鏈表的開頭節點
ListNode oddStart = null;
// 奇數鏈表的結尾節點
ListNode oddEnd = null;
// 偶數鏈表的開頭節點
ListNode evenStart = null;
// 偶數鏈表的結尾節點
ListNode evenEnd = null;
// 當前遍歷到的節點
ListNode cur = head;
// 當前遍歷到的位置,根據題目意思,從 1 開始
int count = 1;

整個流程如下,遍歷 cur 指針,同步記錄 count,如果 count 記錄的位置是奇數, 則構造奇數鏈表,如果 count 位置記錄的是偶數,則構造偶數鏈表。

構造的過程也比較簡單,以構造奇數鏈表爲例:

如果 oddStart 變量爲空,則說明奇數鏈表未初始化,則直接初始化

oddStart = cur;
oddEnd = cur;

奇數鏈表的頭尾指針都指向 cur,說明初始化完成;

否則,說明奇數鏈表已經初始化過,則把奇數鏈表的尾部的 next 直接連上 cur,然後把奇數鏈表的尾部指針指向 cur,即

oddEnd.next = cur;
oddEnd = cur;

構造偶數鏈表的過程和構造奇數鏈表的過程同理,不贅述。

構造好兩個鏈表以後,把兩個鏈表連接起來即可,連接的邏輯如下:

如果偶數鏈表尾部不爲空,則奇數鏈表一定不爲空,且偶數鏈表的尾部就是變換後鏈表的尾部,即

        if (evenEnd != null) {
            evenEnd.next = null;
        }

最後,要把奇數鏈表尾部的 next 連接上偶數鏈表的頭部

oddEnd.next = evenStart;

完整代碼如下

class Solution {
    // 奇數節點和偶數節點放在一起
    // 所有偶數下標的數一定要在奇數下標數之後(注意:是下標而非值)
    public static ListNode oddEvenList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null) {
            return head;
        }
        ListNode oddStart = null;
        ListNode oddEnd = null;
        ListNode evenStart = null;
        ListNode evenEnd = null;
        ListNode cur = head;
        int count = 1;
        while (cur != null) {
            if ((count & 1) == 1) {
                // 奇數
                if (oddStart == null) {
                    oddStart = cur;
                } else {
                    oddEnd.next = cur;
                }
                oddEnd = cur;
            } else {
                // 偶數
                if (evenStart == null) {
                    evenStart = cur;
                } else {
                    evenEnd.next = cur;
                }
                evenEnd = cur;
            }
            count++;
            cur = cur.next;
        }
        if (evenEnd != null) {
            evenEnd.next = null;
        }
        oddEnd.next = evenStart;
        return oddStart;
    }
}

更多

算法和數據結構筆記

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