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

2021-10-12 20:47:07 字數 2449 閱讀 2637

這道題屬於雙鏈表合併的高階。理解這道題首先需要了解有序雙鏈表合併的解法。

已知鍊錶有序,使用兩個指標指向兩個鍊錶,逐一比較大小移動指標。**很簡單如下所示。

public listnode mergetwolists(listnode l1, listnode l2)  else 

cur = cur.next;

}cur.next = l1 == null ? l2 : l1;

return dummy.next;

}

兩個有序鍊錶合併,我們用到了兩個指標。那麼n個鍊錶,顯然無法儲存n個指標去遍歷和移動。所以需要換種思路,可以對鍊錶逐一進行兩兩合併。但是這樣會導致鍊錶的重複遍歷。此時可以用到歸併排序中的思路:分治法。將鍊錶對半拆分到單鏈表,再進行兩兩合併,這樣就不會有重複遍歷,詳情見方法三。

同時,如果題目不要求空間複雜度,可以使用陣列或集合來快速實現整體的排序,容易理解,見方法一。

擴充套件思路,雙鏈表合併,每次需要比較計算兩個指標大小。那麼k個鍊錶每次需要計算k個指標對應的節點大小。此時可以想到使用優先順序佇列,具體見方法二。

不要求空間複雜度情況,可以借助陣列集合,遍歷所有的鍊錶上的節點,放入集合中,進行排序。再從集合中將其取出,構造新鍊錶

/**

* 如果不限制空間複雜度,可以放到陣列中排序,再拿出

* 時間複雜度o(nlogn) = 遍歷所有值 o(n) + 穩定排序演算法o(nlongn) + 遍歷建立新鍊錶o(n)

*/public listnode mergeklists1(listnode lists)

}alllist.sort(new comparator()

});listnode dummy = new listnode(0);

listnode cur = dummy;

for (listnode node : alllist)

cur.next = null;

return dummy.next;

}

使用大小為鍊錶長度的優先順序佇列,可以將優先順序佇列看成大小為k的小根堆。將k個鍊錶的頭節點全部加入小根堆中。當堆不為空,從堆中彈出堆頂,即最小值,並將當前節點的next指標指向該值,當前節點後移。此時當前節點指向了k個鍊錶中最小的節點,判斷其下乙個節點是否為空,不為空則將下乙個節點加入小根堆中。

/**

* 如果不限制空間複雜度,也可以使用優先順序佇列

*/public listnode mergeklists2(listnode lists)

priorityqueuequeue = new priorityqueue<>(lists.length, new comparator()

});listnode dummy = new listnode(0);

listnode cur = dummy;

for (listnode node : lists)

}while (!queue.isempty())

}return dummy.next;

}

思路類似鍊錶的歸併排序,使用分治法,遞迴將鍊錶拆分,直到每個都為單獨鍊錶,再將其兩兩合併。

這樣避免了鍊錶的重複遍歷。

/**

* 分治法:遞迴拆分鍊錶變成單獨鍊錶,再兩兩合併 思路類似鍊錶的歸併排序

* 時間複雜度:o(nlogk),其中k 鍊錶的數目

*/public listnode mergeklists(listnode lists)

​ public listnode partion(listnode lists, int start, int end)

int mid = start + ((end - start) >> 1);

listnode l1 = partion(lists, start, mid);

listnode l2 = partion(lists, mid + 1, end);

return mergetwolists(l1, l2);

}​ public listnode mergetwolists(listnode l1, listnode l2) else

cur = cur.next;

}cur.next = l1 == null ? l2 : l1;

return dummy.next;

}

git**位址​github.com

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

合併 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個排序鍊錶

合併k個排序鍊錶,並且返回合併後的排序鍊錶。嘗試分析和描述其複雜度。樣例 給出3個排序鍊錶 2 4 null,null,1 null 返回 1 2 4 null 兩兩合併 合併ab得到c 合併cd得到e definition for listnode.public class listnode pu...

合併K個排序鍊錶

從21.合併兩個有序鍊錶的基礎上,我們已經能夠解決兩個有序鍊錶的問題,現在是k個有序鍊錶,我們可以將第一二個有序鍊錶進行合併,然後將新的有序鍊錶再繼續跟第三個有序鍊錶合併,直到將所有的有序鍊錶合併完成。這樣做思路上是可行的,但是演算法的時間複雜度將會很大,具體就不計算了。有興趣的自己計算下。根據思路...