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
題解
閱讀完了題幹以後,顯然都能發現這題的難點實際上是原地算法
不然建一個新鏈表直接把對應位置的節點拷貝進去豈不痛快。。。
當然這種做法是真的 非常 不明智
試想一個百萬級長度的單鏈表,額外做一次拷貝的空間開銷恐怕不需要我多言了吧
這裏博主採用的思路是:
- 求出鏈表的長度
- 若鏈表長度小於3,直接返回
- 找出第一個奇數位置節點標記爲p1,偶數位置節點則標記爲p2
- 找到 p2 的下一節點,拷貝至 px 中,將 px 插入到 p1 之後
- 將 px 賦值給 p1, p2 後移一位
以下是代碼實現:
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)