Leetcode () Merge K Sorted Lists

Source: Internet
Author: User

The topics are as follows:

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

Analysis:

When you think about it for the first time, it's more natural. Intend to follow the idea of merging sort. Each time, select the smallest one in the K element. The minimum time complexity of each selection is O (K), which makes an O (n) second (assuming a total of n elements).

Also note that there are situations that need to be considered, such as lists[i] if the input to a function is likely to be null at the beginning, to be processed to Midway, possibly Lists[i] the corresponding single linked list is changed from Non-null to empty.

This is the first version of the Solution.h function

First edition Solution.h #ifndef leetcodeoj_022_mergeklist_solution_h #define LEETCODEOJ_022_MERGEKLIST_SOLUTION_H #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) {//0 preprocessing, removing a node that is empty from the start
        for (int i=0;i<lists.size (); i++) {if (lists[i]==null) lists.erase (Lists.begin () +i);
        } listnode* Final_list_head=null;
        listnode* Final_list_tail=null;
            while (Lists.size () >0) {int small_list_index=-1;
            listnode* small_list_node=new ListNode (Int_max);
            Vector<int> Change_lists_index; 1 Find the current smallest node for (int i=0;i< (int) lists.size (); i++) {listnode* Current_list_node = lists[i]
                ; if (current_list_node==null) {ChaNge_lists_index.push_back (i);//record already consumed list continue; } if (current_list_node->val<small_list_node->val) {Small_list_node = current
                    _list_node;
                Small_list_index=i;
                } if (Lists.size () ==1&&lists[0]==null)//When the last node (necessarily NULL) is left, exit.

            Break 2 Put the current minimum node into the new list if (final_list_head==null) {listnode* p = new ListNode (small_list_node->v
                AL);
                Final_list_head = p;
            Final_list_tail = p;
                }else{listnode* p = new ListNode (small_list_node->val);
                Final_list_tail->next = p;
            Final_list_tail = p;

            
            } lists[small_list_index]=small_list_node->next; 3 to the already consumed list do process if (!change_lists_index.empty ()) {for (int j= (int) chAnge_lists_index.size () -1;j>=0;j--)///first large and then small to delete, so the most convenient.
                Each deletion does not cause the next marked change of the deleted item {lists.erase (Lists.begin () +change_lists_index[j]);
    }}//while return final_list_head;
}
}; #endif

This is the first version of the main function:

The first version of the main function #include <iostream> #include "Solution.h" listnode* make_list (int* in_arr, int len) {listnode* P_head
    = NULL;
    listnode* p_tail = NULL;
        for (int i=0;i<len;i++) {listnode* p_node=new ListNode (in_arr[i));
            if (P_head = = NULL) {p_head = P_node;
        P_tail = P_node;
            }else {p_tail->next=p_node;
        p_tail=p_tail->next;
} return p_head;
    } void Print_list (listnode* ln) {std::cout<< "list elements are =";
        while (ln!=null) {std::cout<<ln->val<< "\ t";
    ln=ln->next;
    } std::cout<<std::endl;
Return    int main (int argc, const char * argv[]) {int array1[]={1};//int array2[]={2,9};//int array3[]={3,6};//
int array1[]={-30,1,4,7,10};
int array2[]={-20,0,2,5,8,11,14};
    int array3[]={3,6,9,12,15,17,19,20};
    Vector<listnode*> Vec_all;
    listnode* Ln0=null; listnode* ln1 = make_list(Array1,sizeof (array1)/sizeof (int));
listnode* LN2 = make_list (array2,sizeof (array2)/sizeof (int));
    listnode* ln3 = make_list (array3,sizeof (ARRAY3)/sizeof (int));
Print_list (LN1);
Print_list (LN2);
    
    Print_list (LN3);
    Vec_all.push_back (Ln0);
Vec_all.push_back (LN1);
Vec_all.push_back (LN2);
    Vec_all.push_back (LN3);
    Solution S1;
    listnode* Ln_all;
    Ln_all = S1.mergeklists (Vec_all);
    Print_list (Ln_all);
    Std::cout << "022 Hello, world!\n";
return 0; }

The second consideration whether there is room for improvement, every time from the K element to find the smallest 1 elements into the new list of the process, in fact, every time to find the smallest 1 number of processes, this process can be used in the STL algorithm library in the smallest heap to achieve. This will require only O (1) time complexity to find the smallest element from the K element each time, and then the new heap will require only O (LGK) time complexity. The answer is as follows, reference from the official website

ListNode *mergeklists (Vector<listnode *> &lists) {
    Vector<listnode*>::iterator it = Lists.begin () ;
    while (it!= lists.end ()) {
        if (*it = NULL) lists.erase (it);
        else ++it;
    }
    if (Lists.size () < 1) return NULL;

    ListNode *head = null, *cur = NULL;
    Make_heap (Lists.begin (), Lists.end (), comp ());

    while (Lists.size () > 0) {
        if (head = = NULL) head = cur = lists[0];
        else cur = Cur->next = lists[0];

        Pop_heap (Lists.begin (), Lists.end (), comp ());
        int last = Lists.size ()-1;
        if (Lists[last]->next!= NULL) {
            Lists[last] = lists[last]->next;
            Push_heap (Lists.begin (), Lists.end (), comp ());
        else Lists.pop_back ();
    }

    return head;
}

 Class Comp {public
 :
    bool Operator () (const listnode* L, const listnode* R) Const {return
        (L->val > r->val);
    }
;

It should be noted that the Make_heap () function in the STL algorithm is like this.
1 rearranges the elements in the range [first,last) in such a way that they form a heap.
2 the element with the highest value was always pointed by a.
3 The elements are compared using operator< (for the "I"), or comp (for the second): the element with the HIG Hest value is a element for which this would return false when compared to every other element in the range.
In the algorithm of STL, the comparison operator that establishes the maximum pair use is <. Therefore, according to the requirements of the subject, to build the smallest heap, the comparison operator should be used is >.

Update:2014-12-23

Use the smallest heap to do, in fact, the same idea as above.

180 ms struct Comparelistnode {bool operator () (const listnode* A, const listnode* b) Const {return a-& Gt;val > b->val;
    The greater-than symbol is used to establish the minimum heap.
}
}; Class Solution {Public:listnode *mergeklists (vector<listnode *> &lists) {if (lists.size () = 0) R
        Eturn NULL;
        Vector<listnode*> Vector_for_heap;
            for (int i = 0; i < lists.size (); ++i) {if (lists[i) = NULL) continue;
            Vector_for_heap.push_back (Lists[i]);
        Lists[i] = lists[i]->next;
        } std::make_heap (Vector_for_heap.begin (), Vector_for_heap.end (), Comparelistnode ());
        listnode* dummy_head = new ListNode (-1);
        listnode* tail = dummy_head;
        listnode* Refresh_node = NULL;
            while (Vector_for_heap.size () > 0) {refresh_node = Vector_for_heap.front ();
            Tail->next = Vector_for_heap.front ();
            Tail = tail->next; std::p op_heap (Vector_for_heap.begiN (), Vector_for_heap.end (), Comparelistnode ());
            Note that make_heap (), Pop_heap (), push_heap all need to write the comparison function as a parameter if the comparison function is already defined.
            Vector_for_heap.pop_back ();
            Refresh_node = refresh_node->next;
                if (Refresh_node!= NULL) {vector_for_heap.push_back (Refresh_node);
            Push_heap (Vector_for_heap.begin (), Vector_for_heap.end (), Comparelistnode ());
        } tail->next = NULL;
    Return dummy_head->next;
 }
};

Update

2015-03-23

47ms struct Comparelistelement {bool operator () (const listnode* A, const listnode* b) Const {return (  A->val > B->val);

NOTE1: Build small heap} with greater than symbol; Class Solution {Public:listnode *mergeklists (vector<listnode *> &lists) {vector<listnode*>
        Veck;
        listnode* dummyhead = new ListNode (0);
        listnode* tail = dummyhead; for (int i = 0; i < lists.size (); ++i) {if (lists[i)!= null) {//note2: Determine whether null Veck.pus
            H_back (Lists[i]); } std::make_heap (Veck.begin (), Veck.end (), comparelistelement ());
            NOTE3.1 comparator are either all used, or all are not used while (!veck.empty ()) {tail->next = Veck.front ();
            Tail = tail->next; std::p op_heap (Veck.begin (), Veck.end (), comparelistelement ());
            NOTE3.2 comparator either all use, or all do not use Veck.pop_back (); if (Tail->next!= NULL) {veck.push_back (TaiL->next); std::p ush_heap (Veck.begin (), Veck.end (), comparelistelement ());
    NOTE3.3 comparator either all use, or all do not use} return dummyhead->next;
 }
};



Summary extension:

1. Pit One: Make_heap (), Pop_heap (), Push_heap (), note that when using comparator, be consistent, either write or write.

2. Pit Second: C + + algorithm is the default to create the Max heap, if you want to establish min heap, to overload comparator, symbol >.

3. Pit Third: heap push () and vector push () to use, pop () the same.

4. No. Fourth Pit: Validate Input. Line 15 Determines whether the element is null and is not NULL to join the initial veck.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.