n個人選k個c語言 23 合併k個排序鍊錶

2021-10-12 20:47:07 字數 1690 閱讀 8949

合併 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為...