【力扣LeetCode】23 合并K个排序链表

版权声明:本文为原创博客,未经允许,请勿转载。 https://blog.csdn.net/u013095333/article/details/90814730

题目描述(难度难)

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6

链接

https://leetcode-cn.com/problems/merge-k-sorted-lists/

思路

比较好的两种思路
1、与合并两个有序链表一样,K个链表一起从头往尾走,每次选取K个链表中指针指向位置的最小值,这个最小值使用优先队列维护较为合适。
2、链表之间两两合并,可复用两个有序链表合并的代码。

  • 从第一个链表开始,依次合并后面的链表
  • 分治,第一个链表和第二个链表合并,第三个和第四个合并,如此下去
    在这里插入图片描述
    显然,分治算法是很不错的,在这里本文采用这种方法。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
	ListNode* mergeKLists(vector<ListNode*>& lists) {
    	if(lists.size() == 0){
    		return NULL;
    	}
    	if(lists.size() == 1){
    		return lists[0];
    	}
    	if(lists.size() > 1){
    		vector<ListNode*> liststemp;
    		if(lists.size()%2 == 0){
    			for(int i = 0; i < lists.size(); i+=2){
    				ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
    				liststemp.push_back(ans);
    			}
    			lists = liststemp;
    			return mergeKLists(lists);
    		}
    		else{
    			// 这里是 i < lists.size()-1 有所怀疑没有仔细确认导致浪费了一点时间查错
    			for(int i = 0; i < lists.size()-1; i+=2){
    				ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
    				liststemp.push_back(ans);
    			}
    			liststemp.push_back(lists[lists.size()-1]);
    			lists = liststemp;
    			return mergeKLists(lists);
    		}
    	}
    	return NULL;
    }
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* ans = NULL;
        if(l1 == NULL && l2 == NULL){
        	return NULL;
        }
        else if(l1 == NULL){
        	return l2;
        }
        else if(l2 == NULL){
        	return l1;
        }
        else{
        	ListNode* t1 = l1;
        	ListNode* t2 = l2;
        	if(t1->val < t2->val){
        		ans = t1;
        		t1 = t1->next;
        	}
        	else{
        		ans = t2;
        		t2 = t2->next;
        	}
        	ListNode* tans = ans;
        	while(t1&&t2){
        		if(t1->val < t2->val){
	        		tans->next = t1;
	        		t1 = t1->next;
	        		tans = tans->next;
	        	}
	        	else{
	        		tans->next = t2;
	        		t2 = t2->next;
	        		tans = tans->next;
	        	}
        	}
        	while(t1){
        		tans->next = t1;
	        	t1 = t1->next;
	        	tans = tans->next;
        	}
        	while(t2){
        		tans->next = t2;
	        	t2 = t2->next;
	        	tans = tans->next;
        	}
        }
        return ans;
    }
};

debug代码:

#include <bits/stdc++.h>
using namespace std;

  struct ListNode {
     int val;
      ListNode *next;
      ListNode(int x) : val(x), next(NULL) {}
 };

class Solution {
public:
	ListNode* mergeKLists(vector<ListNode*>& lists) {
    	if(lists.size() == 0){
    		return NULL;
    	}
    	if(lists.size() == 1){
    		return lists[0];
    	}
    	if(lists.size() > 1){
    		vector<ListNode*> liststemp;
    		if(lists.size()%2 == 0){
    			for(int i = 0; i < lists.size(); i+=2){
    				ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
    				liststemp.push_back(ans);
    			}
    			lists = liststemp;
    			return mergeKLists(lists);
    		}
    		else{
    			for(int i = 0; i < lists.size()-1; i+=2){
    				ListNode* ans = mergeTwoLists(lists[i], lists[i+1]);
    				liststemp.push_back(ans);
    			}
    			liststemp.push_back(lists[lists.size()-1]);
    			lists = liststemp;
    			
    			return mergeKLists(lists);
    		}
    	}
    	return NULL;
    }
    
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* ans = NULL;
        if(l1 == NULL && l2 == NULL){
        	return NULL;
        }
        else if(l1 == NULL){
        	return l2;
        }
        else if(l2 == NULL){
        	return l1;
        }
        else{
        	ListNode* t1 = l1;
        	ListNode* t2 = l2;
        	if(t1->val < t2->val){
        		ans = t1;
        		t1 = t1->next;
        	}
        	else{
        		ans = t2;
        		t2 = t2->next;
        	}
        	ListNode* tans = ans;
        	while(t1&&t2){
        		if(t1->val < t2->val){
	        		tans->next = t1;
	        		t1 = t1->next;
	        		tans = tans->next;
	        	}
	        	else{
	        		tans->next = t2;
	        		t2 = t2->next;
	        		tans = tans->next;
	        	}
        	}
        	while(t1){
        		tans->next = t1;
	        	t1 = t1->next;
	        	tans = tans->next;
        	}
        	while(t2){
        		tans->next = t2;
	        	t2 = t2->next;
	        	tans = tans->next;
        	}
        }
        return ans;
    }
};

int main()
{
	Solution s;
	
	ListNode* l11 = new ListNode(1);
	ListNode* l12 = new ListNode(4);
	ListNode* l13 = new ListNode(5);
	l11->next = l12;
	l12->next = l13;
	
	while(l11){
		cout << l11->val << endl;
		l11 = l11->next;
	}
	
	ListNode* l21 = new ListNode(1);
	ListNode* l22 = new ListNode(3);
	ListNode* l23 = new ListNode(4);
	l21->next = l22;
	l22->next = l23;
	
	ListNode* l31 = new ListNode(2);
	ListNode* l32 = new ListNode(6);
	l31->next = l32;
	
	vector<ListNode*> test;
	test.push_back(l11);
	test.push_back(l21);
	test.push_back(l31);

	ListNode* ans = s.mergeKLists(test);
	
	while(ans){
		cout << ans->val << " ";
		ans = ans->next;
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/u013095333/article/details/90814730
今日推荐