• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
haipali
博客园    首页    新随笔    联系   管理    订阅  订阅

算法 -- 合并K个升序链表

原题:
23. 合并K个升序链表
困难
2.4K
相关企业
给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:

输入:lists = []
输出:[]
示例 3:

输入:lists = [[]]
输出:[]

提示:

k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4

解法:

  1. 暴力遍历加合并链表:两个两个合并,傻办法但有效
    上代码
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        ListNode res = null;
        for(int i=0;i<lists.length;i++){
            res = mergeL(res,lists[i]);
        }
        return res;
    }
    public ListNode mergeL(ListNode list1, ListNode list2){
        if(list1 == null || list2 == null){
            return list1 != null ? list1 :list2;
        }
        ListNode head = new ListNode(0);
        ListNode tail = head, p1 = list1,p2 = list2;
        while(p1 != null && p2 != null){
            if(p1.val <= p2.val){
                tail.next = p1;
                p1 = p1.next;
            }else{
                tail.next = p2;
                p2 = p2.next;
            }
            tail = tail.next;
        }
        tail.next = p1 != null ? p1:p2;
        return head.next;
    }
}
  • 大佬优雅版
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0) return null;
        ListNode[] list1 = new ListNode[lists.length - 1];
        System.arraycopy(lists, 1, list1, 0, lists.length - 1);
        return mergeTwoLists(lists[0], mergeKLists(list1));
    }

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1 == null) return list2;
        if(list2 == null) return list1;
        ListNode head = list1.val <= list2.val ? list1 : list2;
        head.next = mergeTwoLists(head.next, list1.val <= list2.val ? list2 : list1);
        return head;
    }
}

2.使用优先队列
由于优先队列可以边插变排序,包括链表,所以可以用该队列替换合并链表的操作
上代码:

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        ListNode res = new ListNode(0);
        ListNode cur = res;
        PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val - o2.val;
            }
        });
        for(ListNode list: lists){
            if(list == null)
            continue;
            pq.add(list);
        }
        while(!pq.isEmpty()){
            ListNode nex = pq.poll();
            cur.next = nex;
            cur = cur.next;
            if(nex.next != null){
                pq.add(nex.next);
            }
        }
        return res.next;
    }
}
  1. 分支合并
    就是在第一个方法基础上的优化,即一次循环两两合并,合并一半的链表长度
  • 可以使用递归的方式来分治
    代码:
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        int n = lists.length;
        if(n == 0)return null;
        if(n == 1)return lists[0];
        if(n == 2)return mergeL(lists[0],lists[1]);
        int mid = n/2;
        ListNode[] resList1 = new ListNode[mid];
        ListNode[] resList2 = new ListNode[n-mid];
        for(int i=0;i<mid;i++){
            resList1[i] = lists[i];
        }
        for(int i = mid,j=0;i<n;i++,j++){
            resList2[j] = lists[i];
        }
        return mergeL(mergeKLists(resList1),mergeKLists(resList2));
    }
    public ListNode mergeL(ListNode list1, ListNode list2){
        if(list1 == null || list2 == null){
            return list1 != null ? list1 :list2;
        }
        ListNode head = new ListNode(0);
        ListNode tail = head, p1 = list1,p2 = list2;
        while(p1 != null && p2 != null){
            if(p1.val <= p2.val){
                tail.next = p1;
                p1 = p1.next;
            }else{
                tail.next = p2;
                p2 = p2.next;
            }
            tail = tail.next;
        }
        tail.next = p1 != null ? p1:p2;
        return head.next;
    }
}
posted @ 2023-03-17 16:15  蓝光水母  阅读(28)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3