Java實(shí)現(xiàn)合并多個(gè)升序鏈表
前言
本文主要介紹如何將多個(gè)小的升序鏈表合并一個(gè)大的升序鏈表。
需求描述
給出K個(gè)升序鏈接,要求把這K個(gè)升序鏈表合并成一個(gè),并且這個(gè)鏈表也是升序的。
例如:A = [1,5,6], B = [2,3,8], C = [4,4,9] 將這3個(gè)鏈表合并成一個(gè)鏈表D,合并后D = [1,2,3,4,4,5,6,8,9],并且將D的第一個(gè)節(jié)點(diǎn)返回。
思路解析
我們可以采用優(yōu)先級(jí)隊(duì)列來實(shí)現(xiàn),先把每個(gè)鏈表的頭結(jié)點(diǎn)放到一個(gè)優(yōu)先級(jí)隊(duì)列里,優(yōu)先級(jí)隊(duì)列也叫小根堆。
在放小根堆的時(shí)候,誰小就把誰放在最上面。需要注意的是,我們放入的時(shí)候,放入的是節(jié)點(diǎn),所以通過這個(gè)節(jié)點(diǎn)是可以訪問整個(gè)鏈表的。
我們看下處理過程:
- 首先把每個(gè)鏈接的頭結(jié)點(diǎn)放入小根堆中:
1,2,4。 - 首先彈出最小的值:
1。 - 把
1節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)5放入小根堆中,此時(shí)小根堆會(huì)自動(dòng)調(diào)整順序,此時(shí)為:2, 4, 5。 - 將
2節(jié)點(diǎn)彈出,讓1節(jié)點(diǎn)的next指針指向2節(jié)點(diǎn),并且將2節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)6放入小根堆,此時(shí)已彈出的節(jié)點(diǎn)為1,2,而小根堆為4, 5, 6。 - 將
4節(jié)點(diǎn)彈出,讓2節(jié)點(diǎn)的next指針指向4節(jié)點(diǎn),并且將4節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)4放入小根堆中,此時(shí)已彈出的節(jié)點(diǎn)為1,2,4,而小根堆為4, 5, 6。 - 依此類推,每彈出一個(gè)節(jié)點(diǎn),拼接在已彈出節(jié)點(diǎn)的后面,并將彈出節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)放入小根堆中,直到小根堆中所有的元素全部彈出。
好了,現(xiàn)在整體思路有了,但是現(xiàn)在是不是有個(gè)疑問?我們?cè)谧鏊惴〞r(shí),使用到了優(yōu)先隊(duì)列,那么我們可以使用系統(tǒng)自帶的優(yōu)先隊(duì)列嗎?
個(gè)人感覺,如果是面試時(shí),這個(gè)系統(tǒng)自帶的類只是題目中很小的一部分,比如上面的題目,主要考察的是如何實(shí)現(xiàn)這個(gè)過程,而不是考察如何實(shí)現(xiàn)優(yōu)先隊(duì)列的,如果沒有特殊要求不讓使用的話,是可以使用的。當(dāng)然,如果考察是要實(shí)現(xiàn)一個(gè)優(yōu)先隊(duì)列,我要是直接new一個(gè)PriorityQueue,我估計(jì)面試官會(huì)一巴掌把我拍出來。
代碼實(shí)現(xiàn)
鏈表節(jié)點(diǎn)定義如下:
public class ListNode {
public int val;
public ListNode next;
}
因?yàn)槭切「?,需要一個(gè)排序算法,所以定義一個(gè)比較器如下:
public class ListNodeComparator implements Comparator<ListNode> {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
}
合并鏈接:
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null) {
return null;
}
PriorityQueue<ListNode> heap = new PriorityQueue<>(new ListNodeComparator());
for (int i = 0; i < lists.length; i++) {
if (lists[i] != null) {
heap.add(lists[i]);
}
}
if (heap.isEmpty()) {
return null;
}
ListNode head = heap.poll();
ListNode pre = head;
if (pre.next != null) {
heap.add(pre.next);
}
while (!heap.isEmpty()) {
ListNode cur = heap.poll();
pre.next = cur;
pre = cur;
if (cur.next != null) {
heap.add(cur.next);
}
}
return head;
}
這個(gè)方法參數(shù)lists代表要傳進(jìn)來多少個(gè)鏈表,方法合并多個(gè)鏈表后,返回鏈表的第一個(gè)節(jié)點(diǎn)。
時(shí)間復(fù)雜度
假設(shè)有M個(gè)鏈表,M個(gè)鏈表的總節(jié)點(diǎn)個(gè)數(shù)為N。此時(shí),對(duì)于小根堆來說,他的規(guī)模大小為M,則對(duì)于小根堆來說他的操作時(shí)間復(fù)雜度為O(logM),一共有N個(gè)節(jié)點(diǎn),所以時(shí)間復(fù)雜度為O(N*logM)。
總結(jié)
本文主要介紹如何將多個(gè)小的升序鏈表合并一個(gè)大的升序鏈表,介紹了實(shí)現(xiàn)這個(gè)功能的思路分析,使用優(yōu)先隊(duì)列自動(dòng)排序的特性實(shí)現(xiàn)了這個(gè)功能,當(dāng)然這里我們使用的是系統(tǒng)自帶的優(yōu)先隊(duì)列,其實(shí)也可以自己實(shí)現(xiàn)一個(gè),個(gè)人感覺沒太必要,就先偷個(gè)懶 。更多相關(guān)Java 合并升序鏈表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
到此這篇關(guān)于Java實(shí)現(xiàn)合并多個(gè)升序鏈表的文章就介紹到這了,更多相關(guān)Java 合并升序鏈表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Java數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列的兩種方法小結(jié)
下面小編就為大家分享一篇基于Java數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列的兩種方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12
SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式
這篇文章主要介紹了SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
java中的阻塞隊(duì)列應(yīng)用場(chǎng)景及代碼實(shí)例
這篇文章主要介紹了java中的阻塞隊(duì)列應(yīng)用場(chǎng)景及代碼實(shí)例阻塞隊(duì)列是一種特殊的隊(duì)列,它提供了線程安全的操作,并在隊(duì)列為空或滿時(shí)提供了阻塞的功能,阻塞隊(duì)列通常用于多線程場(chǎng)景,其中生產(chǎn)者線程向隊(duì)列中添加元素,而消費(fèi)者線程從隊(duì)列中獲取元素,需要的朋友可以參考下2024-01-01
SpringBoot左腳進(jìn)門之Maven管理家具體步驟
Maven 是一個(gè)項(xiàng)目管理和整合工具,通過對(duì) 目錄結(jié)構(gòu)和構(gòu)建生命周期 的標(biāo)準(zhǔn)化, 使開發(fā)團(tuán)隊(duì)用極少的時(shí)間就能夠自動(dòng)完成工程的基礎(chǔ)構(gòu)建配置,本文介紹SpringBoot左腳進(jìn)門之Maven管理家具體步驟,感興趣的朋友一起看看吧2024-12-12
關(guān)于Java中數(shù)組切片的幾種方法(獲取數(shù)組元素)
這篇文章主要介紹了關(guān)于Java中數(shù)組切片的幾種方法(獲取數(shù)組元素),切片是數(shù)組的一個(gè)引用,因此切片是引用類型,在進(jìn)行傳遞時(shí),遵守引用傳遞的機(jī)制,需要的朋友可以參考下2023-05-05
詳解eclipse項(xiàng)目中的.classpath文件原理
這篇文章介紹了eclipse項(xiàng)目中的.classpath文件的原理,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12

