【力扣LeetCode】23 合併K個排序鏈表

題目描述(難度難)

合併 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章