合并K个排序链表--优先队列解决

0x01.问题

合并 k 个排序链表,返回合并后的排序链表。
输入示例:
[
1->4->5,
1->3->4,
2->6
]
输出示例:
1->1->2->3->4->4->5->6

本题是上题的升级版 合并两个有序链表

C++结构体:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 C++函数形式: ListNode* mergeKLists(vector<ListNode*>& lists) 

0x02.简要分析

与上个问题不同的是,这次要求的是k个链表的排序,而不仅仅是两个链表的排序了。

但基本的思路还是不变的,还是从每个里面拿出一个最小值,加在结果链表上。

但考虑到这里链表由很多,所以暴力的取出肯定是不可取的。

有一个思路是将多个链表最终转换为两个链表的合并,这其实就是分治的思路,肯定是可以的,在这里,我们使用一种更加好理解的解决办法。

最暴力的思路应该就是将所有的链表都转换为数组,目的是什么,就是为了排序简单,那么,我们可不可以在遍历的时候做到排序了,也就是说放入一个有序的容器内,没错,优先队列 就可以做到,我们可以维护一个小顶堆,也就是最小值优先队列,先把头节点入优先队列,每次拿出的时候,再把它的下一个节点入优先队列,因为优先队列的优先级的关系,所以放入的数据会变成有序的,这样,我们每次只要从队头拿出一个元素放入结果链表中就行了。

借助优先队列的帮助,这个问题就变得非常简单了,只要不断得入队出队,就完成了这个排序得过程。

0x03.解决代码–优先队列

class Solution {
public:
    struct mycomp{
        bool operator()(ListNode* a,ListNode* b){
            return a->val>b->val;
        }    
    };
    ListNode* mergeKLists(vector<ListNode*>& lists) {
          priority_queue<ListNode*, vector<ListNode*>, mycomp> queue;
          for(ListNode*head:lists){
              if(head) queue.push(head);
          }
          ListNode* dummy = new ListNode(-1);
          ListNode* temp = dummy;
          while(!queue.empty()){
              ListNode* p = queue.top();
              queue.pop();
              if(p->next) queue.push(p->next);
              temp->next=p;
              temp=temp->next;
          }
          return dummy->next;
    }
};

class Solution {
	public ListNode mergeKLists(ListNode[] lists) {
		if(lists==null || lists.length==0) {
			return null;
		}
		//创建一个堆,并设置元素的排序方式
		PriorityQueue<ListNode> queue = new PriorityQueue(new Comparator<ListNode>() {
			public int compare(ListNode o1, ListNode o2) {
				return (o1.val - o2.val);
			}
		});
		//遍历链表数组,然后将每个链表的每个节点都放入堆中
		for(int i=0;i<lists.length;i++) {
			while(lists[i] != null) {
				queue.add(lists[i]);
				lists[i] = lists[i].next;
			}
		}
		ListNode dummy = new ListNode(-1);
		ListNode head = dummy;
		//从堆中不断取出元素,并将取出的元素串联起来
		while( !queue.isEmpty() ) {
			dummy.next = queue.poll();
			dummy = dummy.next;
		}
		dummy.next = null;
		return head.next;
	}
}

ATFWUS --Writing By 2020–03–23

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATFWUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值