合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。
示例:
輸入:
[ 1->4->5,
1->3->4,
2->6
]輸出: 1->1->2->3->4->4->5->6
合併兩個有序鍊錶的公升級版,參考網上思路提供四種解法。
比如鍊錶數量為5個,第一次將1和4合併、2和5合併、3落單,第二次將1與3合併,第三次合併最後兩條,這裡k的選取以及n的更新要注意,k選擇(n+1)/2而不是n/2,是為了兼顧鍊錶個數為奇數和偶數的情況,k始終能從後半段開始。
class solution
n = k; //每次數量減半
}return lists[0];
}listnode* mergetwolists(listnode* l1, listnode* l2)else
q = q->next;
}if(l1 != null) q->next = l1;
else if(l2 != null) q->next = l2;
return dummy->next;}};
class solution
listnode* helper(vector& lists, int start, int end)
listnode* mergetwolists(listnode* l1, listnode* l2)else
q = q->next;
}if(l1 != null) q->next = l1;
else if(l2 != null) q->next = l2;
return dummy->next;}};
將每個鍊錶的首元素加入最小堆中,則自動在堆中排好了序,然後取出堆首元素作為合併鍊錶的首元素,緊接著將該元素的下乙個節點加入堆中,依次類推,直到堆中最後元素被取完為止。這種解法的**看起來也是最簡潔的,平日裡堆這種資料結構用得少,需要多加練習。
class solution ;
priority_queue, decltype(cmp)> q(cmp);
for(auto node: lists)
listnode* dummy = new listnode(-1);
listnode* cur = dummy;
while(!q.empty())
return dummy->next;}};
遍歷所有鍊錶的元素,找到最大值和最小值,同時在遍歷的過程中,記錄每個元素值及其出現的次數,最後再重建合併鍊錶的過程中,從最小值遍歷到最大值,讀取雜湊表中對應的元素值以及出現次數,依此新建結點。
class solution
}listnode* dummy = new listnode(-1);
listnode* cur = dummy;
for(int i = mn; i <= mx; i++)
}return dummy->next;}};
四種解法的耗時對比如下,從下到上,依次是解法一到解法四:
n個人選k個c語言 合併K個排序鍊錶
這道題屬於雙鏈表合併的高階。理解這道題首先需要了解有序雙鏈表合併的解法。已知鍊錶有序,使用兩個指標指向兩個鍊錶,逐一比較大小移動指標。很簡單如下所示。public listnode mergetwolists listnode l1,listnode l2 else cur cur.next cur...
23 合併k個排序鍊錶C
方法一 簡單方法.時間複雜度o k 2n 空間複雜度o 1 class solution else mergehead mergetemp while alist blist else if alist mergetemp next alist if blist mergetemp next bli...
23 合併K個排序鍊錶
合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。示例 輸入 1 4 5,1 3 4,2 6 輸出 1 1 2 3 4 4 5 6 偷懶直接複製了以前的堆的 所有看上去長了點 class priorityqueue priority是設定優先順序 true為大根堆 false為...