力扣第 21 题「 合并两个有序链表」
//将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。//////// 示例 1://////输入:l1 = [1,2,4], l2 = [1,3,4]//输出:[1,1,2,3,4,4]////// 示例 2://////输入:l1 = [], l2 = []//输出:[]////// 示例 3://////输入:l1 = [], l2 = [0]//输出:[0]////////// 提示:////// 两个链表的节点数目范围是 [0, 50]// -100 <= Node.val <= 100// l1 和 l2 均按 非递减顺序 排列//// Related Topics 递归 链表// 👍 2346 👎 0//leetcode submit region begin(Prohibit modification and deletion)/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {// 记录最终结果头结点ListNode res = new ListNode(-1);// 增加res引用,用于链表前进ListNode temp = res;// 判断两个链表nullwhile (list1 != null && list2 != null) {// 值小的加入到结果链表上,链表前进一步if (list1.val < list2.val) {temp.next = list1;list1 = list1.next;} else {temp.next = list2;list2 = list2.next;}temp = temp.next;}if (list1 != null) {temp.next = list1;// list2为null,将list1后面所有链表加入就行,不需要链表前进了// list1 = list1.next;}if (list2 != null) {temp.next = list2;// list2 = list2.next;}return res.next;}}//leetcode submit region end(Prohibit modification and deletion)
力扣第 23 题「 合并K个升序链表」:
合并 k 个有序链表的逻辑类似合并两个有序链表,难点在于,如何快速得到 k 个节点中的最小节点,接到结果链表上?
这里我们就要用到 优先级队列(二叉堆) 这种数据结构,把链表节点放入一个最小堆,就可以每次获得 k 个节点中的最小节点:
ListNode mergeKLists(ListNode[] lists) {if (lists.length == 0) return null;// 虚拟头结点ListNode dummy = new ListNode(-1);ListNode p = dummy;// 优先级队列,最小堆PriorityQueue<ListNode> pq = new PriorityQueue<>(lists.length, (a, b)->(a.val - b.val));// 将 k 个链表的头结点加入最小堆for (ListNode head : lists) {if (head != null)pq.add(head);}while (!pq.isEmpty()) {// 获取最小节点,接到结果链表中ListNode node = pq.poll();p.next = node;if (node.next != null) {pq.add(node.next);}// p 指针不断前进p = p.next;}return dummy.next;}
