面试算法78:合并排序链表

题目

输入k个排序的链表,请将它们合并成一个排序的链表。

分析:利用最小堆选取值最小的节点

用k个指针分别指向这k个链表的头节点,每次从这k个节点中选取值最小的节点。然后将指向值最小的节点的指针向后移动一步,再比较k个指针指向的节点并选取值最小的节点。重复这个过程,直到所有节点都被选取出来。

java 复制代码
public class Test {
    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = new ListNode(2);
        ListNode listNode3 = new ListNode(3);
        ListNode listNode4 = new ListNode(4);
        ListNode listNode5 = new ListNode(5);
        ListNode listNode6 = new ListNode(6);
        ListNode listNode7 = new ListNode(7);
        ListNode listNode8 = new ListNode(8);
        ListNode listNode9 = new ListNode(9);

        listNode1.next = listNode4;
        listNode4.next = listNode7;

        listNode2.next = listNode5;
        listNode5.next = listNode8;

        listNode3.next = listNode6;
        listNode6.next = listNode9;

        ListNode[] lists = {listNode1, listNode2, listNode3};
        ListNode result = mergeKLists(lists);
        while (result != null) {
            System.out.println(result.val);
            result = result.next;
        }
    }

    public static ListNode mergeKLists(ListNode[] lists) {
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;

        PriorityQueue<ListNode> minHeap = new PriorityQueue<>((n1, n2) -> n1.val - n2.val);
        for (ListNode list : lists) {
            if (list != null) {
                minHeap.offer(list);
            }
        }

        while (!minHeap.isEmpty()) {
            ListNode least = minHeap.poll();
            cur.next = least;
            cur = least;

            if (least.next != null) {
                minHeap.offer(least.next);
            }
        }

        return dummy.next;
    }
}

分析:按照归并排序的思路合并链表

输入的k个排序链表可以分成两部分,前k/2个链表和后k/2个链表。如果将前k/2个链表和后k/2个链表分别合并成两个排序的链表,再将两个排序的链表合并,那么所有链表都合并了。合并k/2个链表与合并k个链表是同一个问题,可以调用递归函数解决。

java 复制代码
public class Test {
    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = new ListNode(2);
        ListNode listNode3 = new ListNode(3);
        ListNode listNode4 = new ListNode(4);
        ListNode listNode5 = new ListNode(5);
        ListNode listNode6 = new ListNode(6);
        ListNode listNode7 = new ListNode(7);
        ListNode listNode8 = new ListNode(8);
        ListNode listNode9 = new ListNode(9);

        listNode1.next = listNode4;
        listNode4.next = listNode7;

        listNode2.next = listNode5;
        listNode5.next = listNode8;

        listNode3.next = listNode6;
        listNode6.next = listNode9;

        ListNode[] lists = {listNode1, listNode2, listNode3};
        ListNode result = mergeKLists(lists);
        while (result != null) {
            System.out.println(result.val);
            result = result.next;
        }
    }

    public static ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 0) {
            return null;
        }

        return mergeLists(lists, 0, lists.length);
    }

    private static ListNode mergeLists(ListNode[] lists, int start, int end) {
        if (start + 1 == end) {
            return lists[start];
        }

        int mid = (start + end) / 2;
        ListNode head1 = mergeLists(lists, start, mid);
        ListNode head2 = mergeLists(lists, mid, end);
        return merge(head1, head2);
    }

    private static ListNode merge(ListNode head1, ListNode head2) {
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;
        while (head1 != null && head2 != null) {
            if (head1.val < head2.val) {
                cur.next = head1;
                head1 = head1.next;
            }
            else {
                cur.next = head2;
                head2 = head2.next;
            }

            cur = cur.next;
        }
        cur.next = head1 == null ? head2 : head1;
        return dummy.next;
    }
}
相关推荐
C++ 老炮儿的技术栈2 小时前
UDP 与 TCP 的区别是什么?
开发语言·c++·windows·算法·visual studio
殇者知忧2 小时前
【论文笔记】若干矿井粉尘检测算法概述
深度学习·神经网络·算法·随机森林·机器学习·支持向量机·计算机视觉
mochensage4 小时前
C++信息学竞赛中常用函数的一般用法
java·c++·算法
chengooooooo4 小时前
leetcode Top100 238. 除自身以外数组的乘积|数组系列
算法·leetcode
GUIQU.4 小时前
【每日一题 | 2025年6.2 ~ 6.8】第16届蓝桥杯部分偏简单题
算法·蓝桥杯·每日一题
weixin_527550405 小时前
初级程序员入门指南
javascript·python·算法
乄夜5 小时前
嵌入式面试高频(5)!!!C++语言(嵌入式八股文,嵌入式面经)
c语言·c++·单片机·嵌入式硬件·物联网·面试·职场和发展
嘉陵妹妹7 小时前
深度优先算法学习
学习·算法·深度优先
GalaxyPokemon7 小时前
LeetCode - 53. 最大子数组和
算法·leetcode·职场和发展
拉不动的猪7 小时前
安卓和ios小程序开发中的兼容性问题举例
前端·javascript·面试