合并k个已排序的链表——NC.51

题目描述

合并 k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。

[{1,2,3},{4,5,6,7}]

{1,2,3,4,5,6,7}

解决方法一

遍历链表数组,两两合并链表。其中合并两个有序链表也是一个算法题,点击此处查看

import java.util.*;
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if (lists.size() == 0) return null;
        if (lists.size() == 1) return lists.get(0);
        ListNode res = lists.get(0);
        for (int i = 1; i < lists.size(); i++) {
            res = mergeTwoLists(res, lists.get(i));
        }
        return res;
    }
    
    public ListNode mergeTwoLists(ListNode head1, ListNode head2) {
        if (head1 == null) return head2;
        if (head2 == null) return head1;
        
        if (head1.val < head2.val) {
            head1.next = mergeTwoLists(head1.next, head2);
            return head1;
        } else {
            head2.next = mergeTwoLists(head2.next, head1);
            return head2;
        }
    }
}

解决方法二

使用优先队列,其本质也就是大小堆。以每个链表头节点大小为标准,小的优先放入队列。

然后,由于cur是逐个节点遍历的,每次cur.next都被赋值为当前队列中队首元素最小的节点(也就是每次都会找到剩余链表中最小节点连接到cur后面)。于此同时,还需要将每一步寻找到最小节点的所在的链表的剩余节点,添加到队列中。

在这里插入图片描述

import java.util.*;
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if (lists == null || lists.size() == 0) return null;
        PriorityQueue<ListNode> queue = new PriorityQueue<ListNode>(lists.size(), new Comparator<ListNode>(){
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val < o2.val ? -1 : 1;
            }
        });
        
        for (ListNode node : lists) {
            if (node != null){
                queue.add(node);
            }
        }
        
        ListNode res = new ListNode(-1);
        ListNode cur = res;
        
        while (! queue.isEmpty()) {
            cur.next = queue.poll();
            cur = cur.next;
            if (cur.next != null) {
                queue.add(cur.next);
            }
        }
        return res.next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值