[LeetCode.23]合并K个排序链表

思路,用到分治法 Divide and Conquer Approach。简单来说就是不停的对半划分,比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,开始合并。举个例子来说比如合并6个链表,那么按照分治法,我们首先分别合并1和4,2和5,3和6。这样下一次只需合并3个链表,我们再合并1和3,最后和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;
    	return mergeRecursive(lists,0,lists.size()-1);		    
    }

    ListNode* mergeRecursive(vector<ListNode*>& lists,int leftSize,int rightSize)   //迭代两两或者单个合并
    {
        if(rightSize-leftSize==1)
	    return mergeTwoLists(lists[leftSize],lists[rightSize]);
	if(rightSize==leftSize)
	    return lists[leftSize];
	return mergeTwoLists(mergeRecursive(lists,leftSize,leftSize+((rightSize-leftSize+1)>>1)-1),
		mergeRecursive(lists,leftSize+((rightSize-leftSize+1)>>1),rightSize));
    }
	
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)      //两两合并函数
    {
    	if(l1==NULL || l2==NULL)
	    return (l1==NULL)?l2:l1;
    	ListNode* p1=l1;
	ListNode* p2=l2;
	ListNode* lnHead=NULL;
	if(p1->val>p2->val)
	{
	    lnHead=p2;
	    p2=p2->next;
	}
	else
	{
	    lnHead=p1;
	    p1=p1->next;
	}
	lnHead->next==NULL;
	ListNode* newNode=lnHead;
	while(p1!=NULL && p2!=NULL)
	{
	    if(p1->val>p2->val)
	    {
		newNode->next=p2;
		p2=p2->next;
		newNode=newNode->next;
		newNode->next=NULL;
	    }
	    else
	    {
		newNode->next=p1;
		p1=p1->next;
		newNode=newNode->next;
		newNode->next=NULL;	
	    }
	}
	if(p1==NULL)
	    newNode->next=p2;
	if(p2==NULL)
	    newNode->next=p1;
	return lnHead;
    }
};
ac为99.24%(最高,不太稳定,可能和oj的运行状态有关)

猜你喜欢

转载自blog.csdn.net/weixin_39460182/article/details/80776453
今日推荐