合并 K 个排序链表2025年3月17日 | 阅读 8 分钟 问题陈述 在此陈述中,我们有一个链表列表,其中每个链表都按升序排序。您需要以非降序(升序)合并这些链表,从而获得一个有序列表。 样本测试用例 注意:在阅读本文之前,请尝试先想出一种方法,以便更好地理解。方法 1:暴力枚举法 一种直接的方法是使用第一个列表初始化结果,然后遍历其余列表。对于当前列表中的每个节点,以排序方式将其插入到结果中。 以下是上述方法的 Java 实现 public class MergeKSortedLists { // 链表节点类 static class ListNode { int data; ListNode next; public ListNode(int data) { this.data = data; this.next = null; } } static void printList(ListNode node) { while (node != null) { System.out.print(node.data + " "); node = node.next; } } // 主函数,接受一个链表数组并生成排序后的输出 static ListNode mergeKLists(ListNode[] lists, int last) { for (int i = 1; i <= last; i++) { while (true) { ListNode head0 = lists[0], headI = lists[i]; if (headI == null) break; if (head0.data >= headI.data) { lists[i] = headI.next; headI.next = head0; lists[0] = headI; } else { while (head0.next != null) { if (head0.next.data >= headI.data) { lists[i] = headI.next; headI.next = head0.next; head0.next = headI; break; } head0 = head0.next; if (head0.next == null) { lists[i] = headI.next; headI.next = null; head0.next = headI; head0.next.next = null; break; } } } } } return lists[0]; } // 用于创建新节点的实用函数 static ListNode newNode(int data) { return new ListNode(data); } // 驱动程序以测试上述函数 public static void main(String[] args) { // 链表数量 int k = 3; // 每个列表中的元素数量 int n = 4; // 存储链表头节点的指针数组 ListNode[] lists = new ListNode[k]; lists[0] = newNode(1); lists[0].next = newNode(3); lists[0].next.next = newNode(5); lists[0].next.next.next = newNode(7); lists[1] = newNode(2); lists[1].next = newNode(4); lists[1].next.next = newNode(6); lists[1].next.next.next = newNode(8); lists[2] = newNode(0); lists[2].next = newNode(9); lists[2].next.next = newNode(10); lists[2].next.next.next = newNode(11); // 合并所有列表 ListNode head = mergeKLists(lists, k - 1); // 打印合并后的列表 printList(head); } }输出 ![]() 复杂度分析 时间复杂度: O(n^k-1),因为我们对每个 K 列表都遍历了 n 次。 空间复杂度: O(1)。 方法 2:使用最小堆 此解决方案采用最小堆方法。最初,通过从每个 K 个链表中插入第一个元素来构建一个最小堆。该算法通过从最小堆中提取根元素并将其附加到输出链表来继续。随后,将与提取的元素关联的链表中的下一个元素插入到最小堆中。此过程重复进行,直到最小堆中没有剩余元素,最终产生所需的结果。 算法
注意:最小堆确保在剩余的候选元素中最小的元素始终位于根部,从而有助于构建排序后的合并列表。当最小堆中没有更多元素时,算法终止,表示所有链表都已处理。上述方法的 Java 实现 说明 输出 ![]() 复杂度分析 时间复杂度:O(n*k*logk) 空间复杂度:O(k) 方法 3:使用分治法 该方法涉及迭代地配对排序列表,在每次迭代中将列表总数减半,直到所有列表合并。 按照以下步骤解决问题
上述方法的 Java 实现 输出 ![]() 复杂度分析 时间复杂度:O(n*k^2) 空间复杂度:O(n) 下一个主题最接近给定数字的三元组和 |
我们请求您订阅我们的新闻通讯以获取最新更新。