leetcode23. Merge k Sorted Lists

题目:题目链接

就合并链表?这是hard嘛?就挺离谱的。我都不敢相信。。。

有k个链表,每次将一个链表和新链表合并就可以了。
例如样例:[[1,4,5],[1,3,4],[2,6]],设新链表为l,初始为空链表
首先l与[1,4,5]合并,l = 1,4,5
然后l与[1,3,4]合并,l = 1,1,3,4,4,5
以此类推。
基本上和归并排序一样的,只不过归并排序合并的是数组,这是链表。合并两个链表都会吧,不会最好自己动手模拟一下,就是双指针的用法。
看代码吧:

class Solution {
public:

	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {				//同归并排序
		if (!(l1 && l2)) return l1 ? l1 : l2;   //有一个为空就不用排序了
		ListNode* root = new ListNode();		//创建一个头结点,用来连接排好序的链表
		ListNode* dummy_node = root;			//记得要保存下root,因为后面root会移动
		ListNode* ptr1 = l1;					//指向l1的第0个结点
		ListNode* ptr2 = l2;					//指向l2的第0个结点
		while (ptr1 && ptr2) {					//有一个结点没了,就不比较了
			if (ptr1->val > ptr2->val) {		//如果ptr2->val更小,那就让root的下一个结点是ptr2。反之亦然
				root->next = ptr2;
				ptr2 = ptr2->next;				//记得要向后移
			}
			else {								//同if
				root->next = ptr1;
				ptr1 = ptr1->next;
			}
			root = root->next;					//root要始终指向新链表的尾部
		}
		root->next = ptr1 ? ptr1 : ptr2;		//如果有一个链表还没合并到新链表去,直接让他们合并
		return dummy_node->next;				//注意,返回的是头结点的下一个。因为此时root已经指向新链表的尾部了
	}

	ListNode* mergeKLists(vector<ListNode*>& lists) {
		int len = lists.size();
		if (len == 0) return {};				//没有链表
		ListNode* root = nullptr;				//root是新链表的头指针,为了让lists[0]和其他链表一样,都有前驱结点
		for (int i = 0; i < len; ++i)			//每次将一个链表合并到新链表中
			root = mergeTwoLists(root, lists[i]);//root始终为新链表的头指针
		return root;
	}
};

这个其实挺慢的,200多ms,有没有更简单的方法?有。
我们可以用优先队列,把所有链表的当前最小值都放进去,然后每次挑最小的就可以了。看代码:

class Solution {
public:
	struct cmp {//优写队列从小到大排序
		bool operator()(ListNode* a, ListNode* b) {
			return a->val > b->val;
		}
	};
	priority_queue<ListNode*, vector<ListNode*>, cmp> q;
	ListNode* mergeKLists(vector<ListNode*>& lists) {

		int len = lists.size();
		if (len == 0) return {};
		// priority_queue<ListNode*,vector<ListNode*>,cmp>q;
		ListNode* root = new ListNode();
		ListNode* dummy_node = root;
		for (auto& list : lists) {//先将所有链表的第一个都加入到优先队列中去
			if (list)//空的就算了
				q.push(list);
		}
		while (!q.empty()) {//每次把最小的弹出,接到root后面
			ListNode* min_node = q.top();
			q.pop();
			root->next = min_node;
			root = root->next;
			if (min_node->next)//出去后,把它的后面那个叫进来
				q.push(min_node->next);
		}
		return dummy_node->next;
	}
};

这样速度特别快!

说实在话,这题真不应该是hard。。。。。

加油加油加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值