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ì)列來(lái)實(shí)現(xiàn),先把每個(gè)鏈表的頭結(jié)點(diǎn)放到一個(gè)優(yōu)先級(jí)隊(duì)列里,優(yōu)先級(jí)隊(duì)列也叫小根堆。
在放小根堆的時(shí)候,誰(shuí)小就把誰(shuí)放在最上面。需要注意的是,我們放入的時(shí)候,放入的是節(jié)點(diǎn),所以通過(guò)這個(gè)節(jié)點(diǎn)是可以訪問(wèn)整個(gè)鏈表的。
我們看下處理過(guò)程:
- 首先把每個(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
。 - 依此類(lèi)推,每彈出一個(gè)節(jié)點(diǎn),拼接在已彈出節(jié)點(diǎn)的后面,并將彈出節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)放入小根堆中,直到小根堆中所有的元素全部彈出。
好了,現(xiàn)在整體思路有了,但是現(xiàn)在是不是有個(gè)疑問(wèn)?我們?cè)谧鏊惴〞r(shí),使用到了優(yōu)先隊(duì)列,那么我們可以使用系統(tǒng)自帶的優(yōu)先隊(duì)列嗎?
個(gè)人感覺(jué),如果是面試時(shí),這個(gè)系統(tǒng)自帶的類(lèi)只是題目中很小的一部分,比如上面的題目,主要考察的是如何實(shí)現(xiàn)這個(gè)過(guò)程,而不是考察如何實(shí)現(xiàn)優(yōu)先隊(duì)列的,如果沒(méi)有特殊要求不讓使用的話,是可以使用的。當(dāng)然,如果考察是要實(shí)現(xiàn)一個(gè)優(yōu)先隊(duì)列,我要是直接new
一個(gè)PriorityQueue
,我估計(jì)面試官會(huì)一巴掌把我拍出來(lái)。
代碼實(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)來(lái)多少個(gè)鏈表,方法合并多個(gè)鏈表后,返回鏈表的第一個(gè)節(jié)點(diǎn)。
時(shí)間復(fù)雜度
假設(shè)有M
個(gè)鏈表,M
個(gè)鏈表的總節(jié)點(diǎn)個(gè)數(shù)為N
。此時(shí),對(duì)于小根堆來(lái)說(shuō),他的規(guī)模大小為M
,則對(duì)于小根堆來(lái)說(shuō)他的操作時(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è)人感覺(jué)沒(méi)太必要,就先偷個(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)文章
SpringBoot集成mqtt的多模塊項(xiàng)目配置詳解
這篇文章主要介紹了SpringBoot集成mqtt的多模塊項(xiàng)目配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04JavaEE多線程中阻塞隊(duì)列的項(xiàng)目實(shí)踐
本文主要介紹了JavaEE多線程中阻塞隊(duì)列的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09偵聽(tīng)消息隊(duì)列的Message Listener類(lèi)示例詳解
Spring AMQP 是基于 Spring 框架的AMQP消息解決方案,提供模板化的發(fā)送和接收消息的抽象層,提供基于消息驅(qū)動(dòng)的 POJO的消息監(jiān)聽(tīng)等,簡(jiǎn)化了我們對(duì)于RabbitMQ相關(guān)程序的開(kāi)發(fā),本文給大家介紹偵聽(tīng)消息隊(duì)列的Message Listener類(lèi),感興趣的朋友一起看看吧2023-12-12定時(shí)任務(wù)注解@Scheduled不生效問(wèn)題及解決
這篇文章主要介紹了定時(shí)任務(wù)注解@Scheduled不生效問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06Spring @Value 設(shè)置默認(rèn)值的實(shí)現(xiàn)
這篇文章主要介紹了Spring @Value 設(shè)置默認(rèn)值的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09