1. 程式人生 > >leetcode題庫——合併k個排序連結串列

leetcode題庫——合併k個排序連結串列

題目描述:

合併 個排序連結串列,返回合併後的排序連結串列。請分析和描述演算法的複雜度。

示例:

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

方法:

/**
 * 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) {
        ListNode* h0=NULL;
        ListNode* fi;
        if(lists.size()!=0)//刪掉所有空表
            for(int i=0;i<lists.size();i++)
                if(lists[i]==NULL)
                    lists.erase(lists.begin()+i);
        if(lists.size()==0) return h0;
        if(lists.size()==1) return lists[0];
        ListNode* flag=merge(lists[0],lists[1]);
        if(lists.size()==2) return flag;
        else
            for(int i=2;i<lists.size();i++)
                flag=merge(flag,lists[i]);
        return flag;
    }
    ListNode* merge(ListNode* l1,ListNode* l2)
    {
        ListNode *h,*p,*q,*s,*t;
        if(l1==NULL) return l2;
        if(l2==NULL) return l1;
        h=(struct ListNode*)malloc(sizeof(ListNode));
        p=l1;q=l2;s=h;
        while(p!=NULL&&q!=NULL)
        {
            if(p->val < q->val)
            {
                s->next=p;
                p=p->next;
                s=s->next;
                continue;
            }
            if(p->val >= q->val)
            {
                s->next=q;
                q=q->next;
                s=s->next;
                continue;
            }
        }
        if(p==NULL&&q!=NULL) s->next=q;
        if(q==NULL&&p!=NULL) s->next=p;
        s=h->next;
        return s;
    }
};

思路:

首先刪掉所有空表;然後對剩下的連結串列進行合併,從前往後依次合併(((1,2),3),4)......這種。這裡合併時可以用之前的合併兩個有序連結串列的方法:https://blog.csdn.net/Dorothy_Xue/article/details/83347027

在此之前嘗試用過類似於二路歸併的方法,但是在每次合併後,兩個連結串列合二為一,lists中刪掉一個節點後,vector下標有所變化,對之後的merge會產生影響,以至報錯,經過數小時除錯無果,遂放棄。