Merge Two Sorted Lists

做了LeetCode21 ,题目的目的是归并两个已经排好序的链表。

思考了一下,解题思路如下:

本题的目的就是将两个排好序的列表重新排序为一个列表
有一点像归并排序的归并阶段
用C++的指针速度应该是比较快的
首先,分别用两个指针指向两个链表的首部
之后比较,将较小值放入新链表中,并且此指针后移,直到有一个指针指向空,之后把非空指针指向的元素及其后面元素全部加到结果链表中

基本代码如下:

class Solution {
public:
	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
		//解决有其中任何一个为空的情况
		if (l1 == NULL&&l2 == NULL)
			return NULL;
		if (l2 == NULL)
			return l1;
		if (l1 == NULL)
			return l2;
		//当两个链表都不为空的时候
		ListNode *point1 = l1, *point2 = l2,*result,*temp;
		//确定链表头
		if (point1->val < point2->val){
			result = point1;
			point1 = point1->next;
		}
		else{
			result = point2;
			point2 = point2->next;
		}
		temp = result;
		//构造链表
		while (point1!=NULL&&point2!=NULL)
		{
			if (point1->val < point2->val){
				temp->next = point1;
				temp = temp->next;
				point1 = point1->next;
			}
			else{
				temp->next = point2;
				temp = temp->next;
				point2 = point2->next;
			}
		}
		if (point1 == NULL&&point2 == NULL)
			return result;
		if (point2 == NULL){
			temp->next = point1;
			return result;
		}
		if (point1 == NULL){
			temp->next = point2;
			return result;
		}
			
	}
};

想了一下,在result赋初值的时候没有必要这么麻烦,做了一点点改进:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
		//解决有其中任何一个为空的情况
		if (l1 == NULL&&l2 == NULL)
			return NULL;
		if (l2 == NULL)
			return l1;
		if (l1 == NULL)
			return l2;
		//当两个链表都不为空的时候
		ListNode *point1 = l1, *point2 = l2,*result,*temp;
		//确定链表头
		result = new ListNode(0);
		temp = result;
		//构造链表
		while (point1!=NULL&&point2!=NULL)
		{
			if (point1->val < point2->val){
				temp->next = point1;
				temp = temp->next;
				point1 = point1->next;
			}
			else{
				temp->next = point2;
				temp = temp->next;
				point2 = point2->next;
			}
		}
		if (point2 == NULL)
			temp->next = point1;
		else if (point1 == NULL)
			temp->next = point2;
		return result->next;
        
    }
};

测试过,速度明显比之前快很多。改进就是先任意设置一个头指针,最后返回的是result的next个元素。

参看其他大神的代码,发现如下解法。

递归求解:

思路是想要找到结果链表中的下一个元素,需要在另一个链表和此链表中的下一个元素中寻找。即将另一个链表中的当前元素和此元素的下一个元素先进行归并操作,在放在这个元素的后面,这就是归并的思路。

代码如下:

	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
		if (l2 == NULL)
			return l1;
		if (l1 == NULL)
			return l2;
		if (l1->val < l2->val){
			l1->next = mergeTwoLists(l1->next, l2);
			return l1;
		}
		else{
			l2->next = mergeTwoLists(l2->next, l1);
			return l2;
		}

其他方案都差不多。

这个问题其实就是一个简化版的归并的部分操作。

To merge k sorted linked lists, one approach is to repeatedly merge two of the linked lists until all k lists have been merged into one. We can use a priority queue to keep track of the minimum element across all k linked lists at any given time. Here's the code to implement this idea: ``` struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; // Custom comparator for the priority queue struct CompareNode { bool operator()(const ListNode* node1, const ListNode* node2) const { return node1->val > node2->val; } }; ListNode* mergeKLists(vector<ListNode*>& lists) { priority_queue<ListNode*, vector<ListNode*>, CompareNode> pq; for (ListNode* list : lists) { if (list) { pq.push(list); } } ListNode* dummy = new ListNode(-1); ListNode* curr = dummy; while (!pq.empty()) { ListNode* node = pq.top(); pq.pop(); curr->next = node; curr = curr->next; if (node->next) { pq.push(node->next); } } return dummy->next; } ``` We start by initializing a priority queue with all the head nodes of the k linked lists. We use a custom comparator that compares the values of two nodes and returns true if the first node's value is less than the second node's value. We then create a dummy node to serve as the head of the merged linked list, and a current node to keep track of the last node in the merged linked list. We repeatedly pop the minimum node from the priority queue and append it to the merged linked list. If the popped node has a next node, we push it onto the priority queue. Once the priority queue is empty, we return the head of the merged linked list. Note that this implementation has a time complexity of O(n log k), where n is the total number of nodes across all k linked lists, and a space complexity of O(k).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值