1. 程式人生 > >Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

第一次嘗試,思路:想象有n列個向量,每當要merge的時候,比較每一列的第一個大小,取下最小的那個節點返回並且將該節點從當前向量中剔除(search函式來完成)。當search函式返回NULL 的時候說明所有的node都被遍歷了一邊,所以標誌著結束。

但是這個演算法的複雜度比較高。假設有n個數字,每個數字在被取走之前都會被遍歷一次,所以第x大的數字會被遍歷x次的,所以複雜度O(n^2)

提醒超時TLE

程式碼:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* search(struct ListNode** lists, int size);

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
    struct ListNode *head,*forward,*next;
    head=(struct ListNode*)malloc(sizeof(struct ListNode));
    head->next=NULL;
    forward=head;
    while((next=search(lists,listsSize))!=NULL){
        forward->next=next;
        forward=next;
    }
    //next=NULL,no Node any more;
    //no need to add the terminated NULL,cause the last node must\
    //terminate with a NULL;
    //forward->next=next;
    forward=head;
    head=forward->next;
    free(forward);
    return head;
    
}

struct ListNode* search(struct ListNode** lists, int size){
    struct ListNode* temp=*lists;
    size_t i=0;
    int ptr;
    for(;i!=size;i++){
        if(temp==NULL) temp=*(lists+i);
        else if((*(lists+i)!=NULL)&&((*(lists+i))->val)<(temp->val)) {
            temp=*(lists+i);//temp save the pointer to smallest val
            ptr=i;
        }
    }
    if(temp==NULL) return NULL;
    *(lists+ptr)=temp->next;
    return temp;
    
}

第二次嘗試:為降低複雜度,犧牲儲存。將所有的連結串列的值複製到陣列中,利用stdlib中的qsort快排達到nlogn的複雜度。

程式碼如下,依舊提醒超時。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
int cmp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b; //由小到大排序
    //return *(int *)b - *(int *)a; 由大到小排序
}

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
    struct ListNode*temp=*lists;
    int array[1000];
    int size=0;  //indicate the size of array
    for(int i=0;i<listsSize;i++)
    {
        struct ListNode*temp=*(lists+i);
        while(temp!=NULL){
            array[size++]=temp->val;
            temp=temp->next;
        }
    }
    if(size==0) return 0;
    qsort(array,size,sizeof(int),cmp);
    struct ListNode* head=(struct ListNode*)malloc(size*sizeof(struct ListNode));
    temp=head;
    int i=0;
    while(i<size){
        temp->val=array[i];
        if(i!=size-1) {
            temp->next=temp+1;
            temp=temp->next;
        }
    }
    temp->next=NULL;
    return head;
    
}

第三次嘗試:

=====================分割線==============

下次再寫