zoukankan      html  css  js  c++  java
  • 23. 合并K个排序链表

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

    示例:

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

    /*
    解题思路:
    不停的对半划分,比如k个链表先划分为合并两个k / 2个链表的任务,再不停的往下划分,
    直到划分成只有一个或两个链表的任务,开始合并。举个例子来说比如合并6个链表,那么按照分治法,
    我们首先分别合并0和3,1和4,2和5。这样下一次只需合并3个链表,我们再合并1和3,最后和2合并就可以了。
    代码中的k是通过(n + 1) / 2 计算的,这里为啥要加1呢,这是为了当n为奇数的时候,k能始终从后半段开始,
    比如当n = 5时,那么此时k = 3,则0和3合并,1和4合并,最中间的2空出来。当n是偶数的时候,加1也不会有影响,
    比如当n = 4时,此时k = 2,那么0和2合并,1和3合并,
    */
    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<vector>
    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.empty()) 
    			return NULL;
    		int n = lists.size();
    		while (n > 1) 
    		{
    			int k = (n + 1) / 2;
    			for (int i = 0; i < n / 2; ++i) 
    			{
    				lists[i] = mergeTwoLists(lists[i], lists[i + k]);
    			}
    			n = k;
    		}
    		return lists[0];
    	}
    	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) 
    	{
    		ListNode *dummy = new ListNode(-1), *cur = dummy;
    		while (l1 && l2) 
    		{
    			if (l1->val < l2->val)
    			{
    				cur->next = l1;
    				l1 = l1->next;
    			}
    			else 
    			{
    				cur->next = l2;
    				l2 = l2->next;
    			}
    			cur = cur->next;
    		}
    		if (l1) cur->next = l1;
    		if (l2) cur->next = l2;
    		return dummy->next;
    	}
    };
    ListNode* CreateListNode(int arr[], int n)
    {
    	ListNode* head;
    	head = new ListNode(arr[0]);
    	ListNode* cur;
    	cur = head;
    	for (int i = 1; i < n; i++)
    	{
    		cur->next = new ListNode(arr[i]);
    		cur = cur->next;
    	}
    	return head;
    }
    int main()
    {
    	vector<ListNode*> lists;
    	int k;
    	cin >> k;
    	while (k--)
    	{
    		int n;
    		cin >> n;
    		int i;
    		int a[100];
    		for (i = 0; i < n; i++)
    		{
    			scanf("%d", &a[i]);
    		}
    		ListNode* head = CreateListNode(a, n);
    		lists.push_back(head);
    	}
    	ListNode* result = Solution().mergeKLists(lists);
    	while (result != NULL)
    	{
    		printf("%d ", result->val);
    		result = result->next;
    	}
    	system("pause");
    	return 0;
    }
    

      

  • 相关阅读:
    andorid jar/库源码解析之Butterknife
    JavaScript DOM 鼠标拖拽
    JavaScript JSON 与 AJAX
    JavaScript DOM 事件模型
    JavaScript DOM 样式操作
    JavaScript DOM 常用尺寸
    JavaScript 日期与计时器
    JavaScript DOM 基础
    JavaScript 数组
    JavaScript 对象拷贝
  • 原文地址:https://www.cnblogs.com/277223178dudu/p/11411522.html
Copyright © 2011-2022 走看看