链表专题之Merge k Sorted Lists leetcode(23)

有了合并两个有序链表做铺垫,合并k个链表就容易实现了,但是,一开始我的想法并不科学:不断合并2个链表,这样一来要合并k-1次,时间复杂度为O(nk),太低效了。既然是合并,为何不用二分合并呢?二分合并只需要O(nlogk)的复杂度。

对于二分合并,要对k个链表做合并,即划分成[0,k/2], [k/2+1,k]两部分,然后做递归。

ListNode* mergeKLists(vector<ListNode*>& lists) {
        int k = lists.size();
        if(k == 0)
            return NULL;
        
        ListNode*head =  mergeKListsHelper(lists, 0, k-1);    //
        
        return head;
        
    }
    ListNode* mergeKListsHelper(vector<ListNode*>& lists, int left, int right) {
        if (left == right)    //递归的终止条件
            return lists[left];
        
        int mid = (left + right) / 2;
        ListNode *l1 = mergeKListsHelper(lists, left, mid);    //递归的对链表进行合并
        ListNode *l2 = mergeKListsHelper(lists, mid + 1, right);
        
        return mergeTwoLists(l1, l2);
    }
    
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {    //此处为两个链表合并的算法,也可以使用递归。
        if (l1 == NULL)
            return l2;
        if (l2 == NULL)
            return l1;
        ListNode *p1 = l1;
        ListNode *p2 = l2;
        ListNode *newlist; 
        if (p1->val < p2->val)
        {
            newlist = p1;
            p1 = p1->next;
        }
        else
        {
            newlist = p2;
            p2 = p2->next;
        }
        ListNode *p = newlist;
        
        while (p1 != NULL && p2 !=NULL)
        {
            if(p1->val < p2->val)
            {
                p->next = p1;
                p1 = p1->next;
                p = p->next;
                
            }
            else
            {
                p->next = p2;
                p2 = p2->next;
                p = p->next;
            }
            
        }
        if(p1 !=NULL)
        {
            p->next = p1;
        }
        
        if(p2 !=NULL)
        {
            p->next = p2;
        }
        
        return newlist;
        
        
    }


猜你喜欢

转载自blog.csdn.net/u012260341/article/details/79532230