【力扣 21】合并两个有序链表 C++题解(优先队列+链表)

57 阅读1分钟

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4] 示例 2:

输入:l1 = [], l2 = [] 输出:[] 示例 3:

输入:l1 = [], l2 = [0] 输出:[0]

提示:

两个链表的节点数目范围是 [0, 50] -100 <= Node.val <= 100 l1 和 l2 均按 非递减顺序 排列


思路

首先定义一个优先队列pq,这个队列的特性是它会自动以升序方式排列其中的元素。然后,遍历两个输入链表list1list2,将其中的每一个元素都加入到优先队列中。这样就得到了一个包含了所有输入元素并且已经排序的队列。

在得到排序后的队列之后,开始创建新的排序链表。创建两个指针list3p3,都初始化为nullptr。然后,开始从优先队列中取出元素。每取出一个元素,就在list3的末尾添加一个新的节点,这个节点的值就是我们刚刚取出的元素。在添加新节点的过程中,使用p3指针来追踪最后一个节点的位置,这样就可以在O(1)的时间复杂度内找到链表的尾部。

在取出并处理完优先队列中的所有元素之后,list3就变成了一个包含了所有输入元素并且已经排序的链表。最后返回list3


AC代码

/*
 * @lc app=leetcode.cn id=21 lang=cpp
 *
 * [21] 合并两个有序链表
 */

// @lc code=start
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
   public:
	ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
		priority_queue<int, vector<int>, greater<int>> pq;
		ListNode *list3, *p3;
		list3 = nullptr;
		p3 = nullptr;
		for (ListNode* p = list1; p != nullptr; p = p->next) {
			pq.push(p->val);
		}
		for (ListNode* p = list2; p != nullptr; p = p->next) {
			pq.push(p->val);
		}
		while (!pq.empty()) {
            int t = pq.top();
            pq.pop();
			if (list3 == nullptr) {
				list3 = new ListNode(t);
				p3 = list3;
			} else {
				p3->next = new ListNode(t);
				p3 = p3->next;
			}
		}
		return list3;
	}
};
// @lc code=end