Interview Question: Merge two sorted singly linked lists without creating new nodes

后端 未结 26 2682
有刺的猬
有刺的猬 2020-12-02 04:09

This is a programming question asked during a written test for an interview. \"You have two singly linked lists that are already sorted, you have to merge them and return a

相关标签:
26条回答
  • 2020-12-02 04:34

    First of all understand the mean of "without creating any new extra nodes", As I understand it does not mean that I can not have pointer(s) which points to an existing node(s).

    You can not achieve it without talking pointers to existing nodes, even if you use recursion to achieve the same, system will create pointers for you as call stacks. It is just like telling system to add pointers which you have avoided in your code.

    Simple function to achieve the same with taking extra pointers:

    typedef struct _LLNode{
        int             value;
        struct _LLNode* next;
    }LLNode;
    
    
    LLNode* CombineSortedLists(LLNode* a,LLNode* b){
        if(NULL == a){
            return b;
        }
        if(NULL == b){
            return a;
        }
        LLNode* root  = NULL;
        if(a->value < b->value){
            root = a;
            a = a->next;
        }
        else{
            root = b;
            b    = b->next;
        }
        LLNode* curr  = root;
        while(1){
            if(a->value < b->value){
                curr->next = a;
                curr = a;
                a=a->next;
                if(NULL == a){
                    curr->next = b;
                    break;
                }
            }
            else{
                curr->next = b;
                curr = b;
                b=b->next;
                if(NULL == b){
                    curr->next = a;
                    break;
                }
            }
        }
        return root;
    }
    
    0 讨论(0)
  • 2020-12-02 04:34

    Here is the code on how to merge two sorted linked lists headA and headB:

    Node* MergeLists1(Node *headA, Node* headB)
    {
        Node *p = headA;
        Node *q = headB;
        Node *result = NULL; 
        Node *pp = NULL;
        Node *qq = NULL;
        Node *head = NULL;
        int value1 = 0;
        int value2 = 0;
        if((headA == NULL) && (headB == NULL))
        {
            return NULL;
        }
        if(headA==NULL)
        {
            return headB;
        }
        else if(headB==NULL)
        {
            return headA;
        }
        else
        {
            while((p != NULL) || (q != NULL))
            {
                if((p != NULL) && (q != NULL))
                {
                    int value1 = p->data;
                    int value2 = q->data;
                    if(value1 <= value2)
                    {
                        pp = p->next;
                        p->next = NULL;
                        if(result == NULL)
                        {
                            head = result = p;
                        }
                        else
                        {
                            result->next = p;
                            result = p;
                        }
                        p = pp;
                    }
                    else
                    {
                        qq = q->next;
                        q->next = NULL;
                        if(result == NULL)
                        {
                            head = result = q;
                        }
                        else
                        {
                            result->next = q;
                            result = q;
                        }
                        q = qq;
                    }
                }
                else
                {
                    if(p != NULL)
                    {
                        pp = p->next;
                        p->next = NULL;
                        result->next = p;
                        result = p;
                        p = pp;
                    }
                    if(q != NULL)
                    {
                        qq = q->next;
                        q->next = NULL;
                        result->next = q;
                        result = q;
                        q = qq;
                    }
                }
            }
        }
        return head;
    }
    
    0 讨论(0)
  • 2020-12-02 04:35

    Look ma, no recursion!

    struct llist * llist_merge(struct llist *one, struct llist *two, int (*cmp)(struct llist *l, struct llist *r) )
    {
    struct llist *result, **tail;
    
    for (result=NULL, tail = &result; one && two; tail = &(*tail)->next ) {
            if (cmp(one,two) <=0) { *tail = one; one=one->next; }
            else { *tail = two; two=two->next; }
            }
    *tail = one ? one: two;
    return result;
    }
    
    0 讨论(0)
  • 2020-12-02 04:35

    I show below an iterative solution. A recursive solution would be more compact, but since we don't know the length of the lists, recursion runs the risk of stack overflow.

    The basic idea is similar to the merge step in merge sort; we keep a pointer corresponding to each input list; at each iteration, we advance the pointer corresponding to the smaller element. However, there's one crucial difference where most people get tripped. In merge sort, since we use a result array, the next position to insert is always the index of the result array. For a linked list, we need to keep a pointer to the last element of the sorted list. The pointer may jump around from one input list to another depending on which one has the smaller element for the current iteration.

    With that, the following code should be self-explanatory.

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        ListNode first = l1;
        ListNode second = l2;
        ListNode head = null;
        ListNode last = null;
    
        while (first != null && second != null) {
            if (first.val < second.val) {
                if (last != null) {
                    last.next = first;
                }
                last = first;
                first = first.next;
            } else {
                if (last != null) {
                    last.next = second;
                }
                last = second;
                second = second.next;
            }
            if (head == null) {
                head = last;
            }
        }
    
        if (first == null) {
            last.next = second;
        }
        if (second == null) {
            last.next = first;
        }
    
        return head;
    }
    
    0 讨论(0)
  • 2020-12-02 04:36
    private static Node mergeLists(Node L1, Node L2) {
    
        Node P1 = L1.val < L2.val ? L1 : L2;
        Node P2 = L1.val < L2.val ? L2 : L1;
        Node BigListHead = P1;
        Node tempNode = null;
    
        while (P1 != null && P2 != null) {
            if (P1.next != null && P1.next.val >P2.val) {
            tempNode = P1.next;
            P1.next = P2;
            P1 = P2;
            P2 = tempNode;
            } else if(P1.next != null) 
            P1 = P1.next;
            else {
            P1.next = P2;
            break;
            }
        }
    
        return BigListHead;
    }
    
    0 讨论(0)
  • 2020-12-02 04:37

    A simple iterative solution.

    Node* MergeLists(Node* A, Node* B)
    {
        //handling the corner cases
    
        //if both lists are empty
        if(!A && !B)
        {
            cout << "List is empty" << endl;
            return 0;
        }
        //either of list is empty
        else if(!A) return B;
        else if(!B) return A;
        else
        {
            Node* head = NULL;//this will be the head of the newList
            Node* previous = NULL;//this will act as the
    
            /* In this algorithm we will keep the
             previous pointer that will point to the last node of the output list.
             And, as given we have A & B as pointer to the given lists.
    
             The algorithm will keep on going untill either one of the list become empty.
             Inside of the while loop, it will divide the algorithm in two parts:
                - First, if the head of the output list is not obtained yet
                - Second, if head is already there then we will just compare the values and keep appending to the 'previous' pointer.
             When one of the list become empty we will append the other 'left over' list to the output list.
             */
             while(A && B)
             {
                 if(!head)
                 {
                     if(A->data <= B->data)
                     {
                         head = A;//setting head of the output list to A
                         previous = A; //initializing previous
                         A = A->next;
                     }
                     else
                     {
                         head = B;//setting head of the output list to B
                         previous = B;//initializing previous
                         B = B->next;
                     }
                 }
                 else//when head is already set
                 {
                     if(A->data <= B->data)
                     {
                         if(previous->next != A)
                             previous->next = A;
                         A = A->next;//Moved A forward but keeping B at the same position
                     }
                     else
                     {
                         if(previous->next != B)
                             previous->next = B;
                         B = B->next; //Moved B forward but keeping A at the same position
                     }
                     previous = previous->next;//Moving the Output list pointer forward
                 }
             }
            //at the end either one of the list would finish
            //and we have to append the other list to the output list
            if(!A)
                previous->next = B;
    
            if(!B)
                previous->next = A;
    
            return head; //returning the head of the output list
        }
    }
    
    0 讨论(0)
提交回复
热议问题