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

后端 未结 26 2681
有刺的猬
有刺的猬 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:23

    I would like to share how i thought the solution... i saw the solution that involves recursion and they are pretty amazing, is the outcome of well functional and modular thinking. I really appreciate the sharing.

    I would like to add that recursion won't work for big lits, the stack calls will overflow; so i decided to try the iterative approach... and this is what i get.

    The code is pretty self explanatory, i added some inline comments to try to assure this.

    If you don't get it, please notify me and i will improve the readability (perhaps i am having a misleading interpretation of my own code).

    import java.util.Random;
    
    
    public class Solution {
    
        public static class Node<T extends Comparable<? super T>> implements Comparable<Node<T>> {
    
            T data;
            Node next;
    
            @Override
            public int compareTo(Node<T> otherNode) {
                return data.compareTo(otherNode.data);
            }
    
            @Override
            public String toString() {
                return ((data != null) ? data.toString() + ((next != null) ? "," + next.toString() : "") : "null");
            }
        }
    
        public static Node merge(Node firstLeft, Node firstRight) {
            combine(firstLeft, firstRight);
            return Comparision.perform(firstLeft, firstRight).min;
    
        }
    
        private static void combine(Node leftNode, Node rightNode) {
            while (leftNode != null && rightNode != null) {
                // get comparision data about "current pair of nodes being analized".
                Comparision comparision = Comparision.perform(leftNode, rightNode);
                // stores references to the next nodes
                Node nextLeft = leftNode.next; 
                Node nextRight = rightNode.next;
                // set the "next node" of the "minor node" between the "current pair of nodes being analized"...
                // ...to be equals the minor node between the "major node" and "the next one of the minor node" of the former comparision.
                comparision.min.next = Comparision.perform(comparision.max, comparision.min.next).min;
                if (comparision.min == leftNode) {
                    leftNode = nextLeft;
                } else {
                    rightNode = nextRight;
                }
            }
        }
    
    /** Stores references to two nodes viewed as one minimum and one maximum. The static factory method populates properly the instance being build */
        private static class Comparision {
    
            private final Node min;
            private final Node max;
    
            private Comparision(Node min, Node max) {
                this.min = min;
                this.max = max;
            }
    
            private static Comparision perform(Node a, Node b) {
                Node min, max;
                if (a != null && b != null) {
                    int comparision = a.compareTo(b);
                    if (comparision <= 0) {
                        min = a;
                        max = b;
                    } else {
                        min = b;
                        max = a;
                    }
                } else {
                    max = null;
                    min = (a != null) ? a : b;
                }
                return new Comparision(min, max);
            }
        }
    
    // Test example....
        public static void main(String args[]) {
            Node firstLeft = buildList(20);
            Node firstRight = buildList(40);
            Node firstBoth = merge(firstLeft, firstRight);
            System.out.println(firstBoth);
        }
    
    // someone need to write something like this i guess...
        public static Node buildList(int size) {
            Random r = new Random();
            Node<Integer> first = new Node<>();
            first.data = 0;
            first.next = null;
            Node<Integer> current = first;
            Integer last = first.data;
            for (int i = 1; i < size; i++) {
                Node<Integer> node = new Node<>();
                node.data = last + r.nextInt(5);
                last = node.data;
                node.next = null;
                current.next = node;
                current = node;
            }
            return first;
        }
    

    }

    0 讨论(0)
  • 2020-12-02 04:23

    My take on the question is as below:

    Pseudocode:

    Compare the two heads A and B. 
    If A <= B, then add A and move the head of A to the next node. 
    Similarly, if B < A, then add B and move the head of B to the next node B.
    If both A and B are NULL then stop and return.
    If either of them is NULL, then traverse the non null head till it becomes NULL.
    

    Code:

    public Node mergeLists(Node headA, Node headB) {
        Node merge = null;
        // If we have reached the end, then stop.
        while (headA != null || headB != null) {
            // if B is null then keep appending A, else check if value of A is lesser or equal than B
            if (headB == null || (headA != null && headA.data <= headB.data)) {
                // Add the new node, handle addition separately in a new method.
                merge = add(merge, headA.data);
                // Since A is <= B, Move head of A to next node
                headA = headA.next;
            // if A is null then keep appending B, else check if value of B is lesser than A
            } else if (headA == null || (headB != null && headB.data < headA.data)) {
                // Add the new node, handle addition separately in a new method.
                merge = add(merge, headB.data);
                // Since B is < A, Move head of B to next node
                headB = headB.next;
            }
        }
        return merge;
    }
    
    public Node add(Node head, int data) {
        Node end = new Node(data);
        if (head == null) {
            return end;
        }
    
        Node curr = head;
        while (curr.next != null) {
            curr = curr.next;
        }
    
        curr.next = end;
        return head;
    }
    
    0 讨论(0)
  • 2020-12-02 04:27
    public static Node merge(Node h1, Node h2) {
    
        Node h3 = new Node(0);
        Node current = h3;
    
        boolean isH1Left = false;
        boolean isH2Left = false;
    
        while (h1 != null || h2 != null) {
            if (h1.data <= h2.data) {
                current.next = h1;
                h1 = h1.next;
            } else {
                current.next = h2;
                h2 = h2.next;
            }
            current = current.next;
    
            if (h2 == null && h1 != null) {
                isH1Left = true;
                break;
            }
    
            if (h1 == null && h2 != null) {
                isH2Left = true;
                break;
            }
        }
    
        if (isH1Left) {
            while (h1 != null) {
                current.next = h1;
                current = current.next;
                h1 = h1.next;
            }
        } 
    
        if (isH2Left) {
            while (h2 != null) {
                current.next = h2;
                current = current.next;
                h2 = h2.next;
            }
        }
    
        h3 = h3.next;
    
        return h3;
    }
    
    0 讨论(0)
  • 2020-12-02 04:28
    Node MergeLists(Node list1, Node list2) {
        //if list is null return other list 
       if(list1 == null)
       {
          return list2;
       }
       else if(list2 == null)
       {
          return list1;
       }
       else
       {
            Node head;
            //Take head pointer to the node which has smaller first data node
            if(list1.data < list2.data)
            {
                head = list1;
                list1 = list1.next;
            }
            else
            {
               head = list2;
               list2 = list2.next;
            }
            Node current = head;
            //loop till both list are not pointing to null
            while(list1 != null || list2 != null)
            {
                //if list1 is null, point rest of list2 by current pointer 
                if(list1 == null){
                   current.next = list2;
                   return head;
                }
                //if list2 is null, point rest of list1 by current pointer 
                else if(list2 == null){
                   current.next = list1;
                   return head;
                }
                //compare if list1 node data is smaller than list2 node data, list1 node will be
                //pointed by current pointer
                else if(list1.data < list2.data)
                {
                    current.next = list1;
                    current = current.next;
                    list1 = list1.next;
                }
                else
                {
                    current.next = list2;
                    current = current.next;
                    list2 = list2.next;
                }
            }      
        return head;
        }      
    }
    
    0 讨论(0)
  • 2020-12-02 04:29
    Node MergeLists(Node node1, Node node2)
    {
       if(node1 == null)
          return node2;
       else (node2 == null)
          return node1;
    
       Node head;
       if(node1.data < node2.data)
       {
          head = node1;
          node1 = node1.next;
       else
       {
          head = node2;
          node2 = node2.next;
       }
    
       Node current = head;
       while((node1 != null) ||( node2 != null))
       {
          if (node1 == null) {
             current.next = node2;
             return head;
          }
          else if (node2 == null) {
             current.next = node1;
             return head;
          }
    
          if (node1.data < node2.data)
          {
              current.next = node1;
              current = current.next;
    
              node1 = node1.next;
          }
          else
          {
              current.next = node2;
              current = current.next;
    
              node2 = node2.next;
          }
       }
       current.next = NULL // needed to complete the tail of the merged list
       return head;
    
    }
    
    0 讨论(0)
  • 2020-12-02 04:29
    LLNode *mergeSorted(LLNode *h1, LLNode *h2) 
    { 
      LLNode *h3=NULL;
      LLNode *h3l;
      if(h1==NULL && h2==NULL)
        return NULL; 
      if(h1==NULL) 
        return h2; 
      if(h2==NULL) 
        return h1; 
      if(h1->data<h2->data) 
      {
        h3=h1;
        h1=h1->next; 
      }
      else 
      { 
        h3=h2; 
        h2=h2->next; 
      }
      LLNode *oh=h3;
      while(h1!=NULL && h2!=NULL) 
      {
        if(h1->data<h2->data) 
        {
          h3->next=h1;
          h3=h3->next;
          h1=h1->next; 
        } 
        else 
        {
          h3->next=h2; 
          h3=h3->next; 
          h2=h2->next; 
        } 
      } 
      if(h1==NULL)
        h3->next=h2;
      if(h2==NULL)
        h3->next=h1;
      return oh;
    }
    
    0 讨论(0)
提交回复
热议问题