Summary of common interview questions in linked list

1. Delete all nodes in the linked list equal to the given value val.

If a node is no longer referred to by Java, it will be automatically deleted
The linked list is as follows:

The given value is assumed to be 3:

Reference code:

 //Delete all nodes with the value of key
    public void removeAllKey(int val){
        if(this.head == null){//If there is no node, return directly
            return;
        }
        ListNode prev = this.head;
        ListNode cur = this.head.next;
        while(cur!=null){//Node is not empty, enter loop
            if(cur.val == val){//Find a node with the same value as the specified value and delete it
                prev.next = cur.next;
                cur = cur.next;//Move backward one bit after deletion
            }else{//Different from the specified value, move one bit backward
                prev = cur;
                cur = cur.next;
            }
        }
        //Finally, judge whether the header node is the value
        if(this.head.val == val){
            this.head = this.head.next;

        }
    }

2. Reverse a single linked list.

Inverting refers to inverting the node, not inverting the value of the node
Before reversing:

After reversal:

Note: the next field of the single chain tail node is null

Reference code:

//Reverse a single linked list
    public ListNode reverseList(){
       //If there is no node or only one node, return directly
        if(head == null||head.next == null){
            return head;
        }
        ListNode cur = head;
        ListNode newHead = null;

        while(cur!=null){
            ListNode curNext = cur.next;//Leave curNext for backward movement
            cur.next = newHead;//Set the next field of this node as newHead
            newHead = cur;//The newHead node moves back one bit
            cur = curNext;//cur moves back one bit
        }
        return newHead;
    }

3. Given a non empty single linked list with head node, return the intermediate node of the linked list. If there are two intermediate nodes, the second intermediate node is returned.

The fast and slow pointer method is adopted. For each step of the slow pointer, the fast pointer takes two steps. When the fast pointer reaches the end, the slow pointer reaches the middle node

At the beginning, both the fast pointer and the slow pointer are in the header node

Last position

Reference code:

//Given a non empty single linked list of the leading node, return the intermediate node of the linked list
    public ListNode middleNode(){
        if(head == null) return head;
        ListNode fast = head;//Quick pointer
        ListNode slow = head;//Slow pointer
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;//Take two steps
            slow = slow.next;//Take a step
        }
        return slow;//Return slow pointer
    }

4. Input a linked list and output the penultimate node in the linked list.

The fast and slow pointer method is adopted. The fast pointer takes k-1 steps first, and then the fast pointer and slow pointer move forward synchronously until the fast pointer reaches the end

The following linked list assumes that k is 2, and the starting position of its speed pointer is:

The final result is:

Reference code:

//Input a linked list and output the penultimate node in the linked list
    //First let the fast pointer go k-1 steps, and then let the fast pointer and the slow pointer go synchronously
    public ListNode findKthToTail(int k){
        if(head == null) return null;//Empty node
        if(k<0){//Illegal coordinates
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while(k-1 != 0){//Handle cases where k may be greater than the length of the linked list
            if(fast.next != null){
                fast = fast.next;
                k--;
            }else{
                return null;
            }
        }
        while(fast.next != null){//Fast and slow pointer synchronization
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

5. Merge the two ordered linked lists into a new ordered linked list and return. The new linked list is composed of all nodes of a given two linked lists.

There are two ordered linked lists:

After the splicing is completed:

Reference code:

    //Merge the two ordered linked lists into a new ordered linked list and return
    public ListNode mergeTowList(ListNode headA,ListNode headB){
        if(headA == null) return headB;
        if(headB == null) return headA;
        if(headA == null && headB == null) return null;

        ListNode newHead = new ListNode(-1);//Apply for a head node, puppet node
        ListNode tmp = newHead;//Move tmp and keep newHead position

        while(headA != null && headB != null){//Connect who is small first until one of them reaches the tail node
            if(headA.val<headB.val){//Link headA
                tmp.next = headA;
                headA = headA.next;
            }else{
                tmp.next = headB;//Link headB
                headB = headB.next;
            }
            tmp = tmp.next;//Move back one bit after connecting
        }
        if(headA == null){//Head a first to tail node
            tmp.next = headB;
        }
        if(headB == null){//headB first to tail node
            tmp.next = headA;
        }
        return newHead.next;//Returns the next node of the puppet node
    }

6. Write code to divide the linked list into two parts based on the given value X. all nodes less than X are arranged before nodes greater than or equal to x, and the order is guaranteed to remain unchanged.

It is assumed that there is the following linked list:

If the given value x is 6

Create two linked lists respectively. The former is less than X and the latter is greater than x. In order to keep the order unchanged, the tail interpolation method should be used

Reference code:

//The linked list is divided into two parts based on the given value x, and all nodes less than X are arranged before nodes greater than or equal to X
    public ListNode partition(int x){
        ListNode cur = this.head;//Used to traverse the specified linked list
        ListNode bs = null;//Start of the previous linked list
        ListNode be = null;//The end of the previous linked list
        ListNode as = null;//The start of the next linked list
        ListNode ae = null;//The end of the last linked list
        while(cur != null) {//Tail interpolation is used to ensure that the order remains unchanged
            if (cur.val < x) {
                if (bs == null) { //Part I first insertion
                    bs = cur;
                    be = cur;
                } else {//Multiple inserted connections
                    be.next = cur;
                    be = be.next;
                }
            } else {
                if (as == null) {//Part II first insertion
                    as = cur;
                    ae = cur;
                } else {//Multiple inserted connections
                    ae.next = cur;
                    ae = ae.next;
                }
            }
            cur = cur.next;//Specify the traversal position of the linked list to move back one bit
        }
        if(bs == null){//If all values are greater than x
            return as;
        }
        //bs!=null
        be.next = as;//be is not empty. The node must have data. Connect it with the next linked list
        if(as != null){//If as is not empty, set the next field of the tail node of the linked list to empty
            ae.next = null;
        }
        return bs;
    }

7. In a sorted linked list, there are duplicate nodes. Please delete the duplicate nodes in the linked list. The duplicate nodes are not retained and the chain header pointer is returned.

Suppose the following linked list is given:

After deleting the duplicate node, it is:

Reference code:

    //Delete the duplicate nodes in an ordered linked list. The duplicate nodes are not retained and the chain header pointer is returned
    public ListNode deleteDuplication(){
        ListNode newHead = new ListNode(-1);//Apply for a puppet node
        ListNode tmp = newHead;//Move tmp to ensure that the puppet node position does not move
        ListNode cur = this.head;
        while(cur != null){
            //cur.next!=null;  Judge whether there is only one node or tail node
            if(cur.next != null && cur.val == cur.next.val){
                //In the process of cur walking again, it is possible that the rest are the same
                while(cur.next != null && cur.val == cur.next.val){
                    cur = cur.next;
                }
                cur = cur.next;//If the cycle is not satisfied, take a step back
            }else{//Tail interpolation
                tmp.next = cur;
                tmp = tmp.next;
                cur = cur.next;
            }
        }
        tmp.next = null;//Set manually to prevent the last node from being repeated
        return newHead.next;
    }

8. Judge whether the linked list has palindrome structure

Example of palindrome structure:

method:

  1. First, find the middle node of the linked list through the fast and slow pointer method

  2. Reverse the linked list from the intermediate node

  3. The head and slow pointers match from head to tail until the two pointers collide. In case of inconsistency, they directly return false, otherwise they return true

    Note: distinguish between odd and even numbers. When even numbers match, compare them one more step

Reference code:

    //Check the palindrome structure of the linked list, for example: 12321
    public boolean chkPalindrome() {
        if (this.head == null) {
            //Not a single node
            return true;
        }
        if (this.head.next == null) {
            //Only one node
            return true;
        }
        //1 find intermediate nodes
        ListNode slow = this.head;
        ListNode fast = this.head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        //The node pointed to by slow is the intermediate node
        //2. Flip
        ListNode cur = slow.next;
        while (cur != null) {
            ListNode curNext = cur.next;//Keep cur next
            cur.next = slow;
            slow = cur;
            cur = curNext;
        }
        //After inversion, slow refers to the last node
        while (slow != head) {
            if (slow.val != head.val) {
                return false;
            }
            if (head.next == slow) {//Even case
                return true;
            }
            head = head.next;
            slow = slow.next;
        }
        return true;
    }

9. Enter two linked lists and find their first common node

The intersecting linked list has Y-type and X-type

The following is a linked list with common nodes:

method:

  1. First, get the length of the two linked lists respectively, and calculate the difference x
  2. Let the long linked list Go x steps first, and then let the two linked lists go while matching the value until the end

Reference code:

 //Enter two linked lists and find their first common node
    public static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null) {
            return null;
        }
        if(headB == null) {
            return null;
        }

        int lenA = 0;
        int lenB = 0;
        //pl: represents the length of the long list, ps: represents the length of the short list
        ListNode pl = headA;
        ListNode ps = headB;

        while(pl != null) {
            lenA++;
            pl = pl.next;
        }
        while(ps != null) {
            lenB++;
            ps = ps.next;
        }
        //The calculated length pl and ps are null, and the header node needs to be returned
        pl = headA;
        ps = headB;
        /*
        lenA And lenB results:
        lenA > lenB
        lenA == lenB
        lenA < lenB
         */
        int len = lenA-lenB;//Difference between two linked lists
        // < 0   == 0   > 0
        if(len < 0) {
            pl = headB;
            ps = headA;
            len = lenB-lenA;
        }
        //Results: pl always points to the long list, ps always points to the short list, and len is always a positive number
        while (len != 0) {
            pl = pl.next;
            len--;
        }
        while (pl != ps) {//Determine whether there is an intersection between two linked lists
            pl = pl.next;
            ps = ps.next;
        }
        //Can not write, assuming that there is no intersection, it is also null
        if(pl == null ) {
            return null;
        }
        return pl;
    }

10. Given a linked list, judge whether there are links in the linked list

The linked list with links is as follows:

Specific form: linked list:

Methods: adopt the fast and slow pointer method. Each step of the slow pointer and two steps of the fast pointer will meet if there are links in the list

Reference code:

    //Judge whether there are links in the linked list
    public boolean hasCycle(){
        ListNode fast = this.head;
        ListNode slow = this.head;

        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(slow == fast){
                break;
            }
        }
        if(fast == null || fast.next == null){
            return false;
        }
        return true;
    }

11. Given a linked list, return the first node from the linked list into the ring. If the linked list is acyclic, null is returned

The fast and slow pointer method is adopted, and the speed of the fast pointer is twice that of the slow pointer

Assumptions:

Derivation of encounter formula:


Since each circle returns to the origin, it is finally equivalent to L=X

Reference code:

    //Given a linked list, return the first node of the linked list into the ring. If the linked list has no ring, return null
    public ListNode detectCycle(){
        ListNode fast = this.head;
        ListNode slow = this.head;

        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(slow == fast){//First meeting
                break;
            }
        }
        if(fast == null || fast.next == null){//No ring
            return null;
        }
        //slow and fast met
        slow = this.head;//slow starts from the starting position and fast starts from the meeting point
        while(fast!=slow){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

Keywords: Java data structure linked list

Added by powah on Mon, 07 Feb 2022 08:45:21 +0200