LeetCode328 算法分析

LeetCode328

題目簡述

分別排列單鏈表的奇數節點和偶數節點
難度:中等
描述:
給定一個單鏈表,把所有的奇數節點和偶數節點分別排在一起。請注意,這裏的奇數節點和偶數節點指的是節點編號的奇偶性,而不是節點的值的奇偶性。
請嘗試 使用原地算法 完成。你的算法的 空間複雜度應爲 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

題解

閱讀完了題幹以後,顯然都能發現這題的難點實際上是原地算法
不然建一個新鏈表直接把對應位置的節點拷貝進去豈不痛快。。。
當然這種做法是真的 非常 不明智
試想一個百萬級長度的單鏈表,額外做一次拷貝的空間開銷恐怕不需要我多言了吧

這裏博主採用的思路是:

  1. 求出鏈表的長度
  2. 若鏈表長度小於3,直接返回
  3. 找出第一個奇數位置節點標記爲p1,偶數位置節點則標記爲p2
  4. 找到 p2 的下一節點,拷貝至 px 中,將 px 插入到 p1 之後
  5. px 賦值給 p1p2 後移一位

以下是代碼實現:

class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if(head == NULL) return head;
        ListNode* p = head;
        int len = 0;
        while(p) {
            len++;
            p = p->next;
        }
        if(len < 3) return head;
        ListNode* p1 = head;
        ListNode* p2 = head -> next;
        ListNode* px = new ListNode;
        for(int i = 2; i < len; i += 2) {
            px = p2 -> next;
            p2 -> next = px -> next;
            px -> next = p1 -> next;
            p1 -> next = px;
            p1 = px;
            p2 = p2 -> next;
        }
        return head;
    }
};

改算法滿足原地算法的條件
即空間複雜度爲O(1)
同時時間複雜度爲O(n)

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