Linked list related interview questions

First question

Problem Description: speed pointer

1) Enter the chain header node. The odd length returns the midpoint, and the even length returns the upper midpoint
2) Enter the chain header node. The odd length returns the midpoint, and the even length returns the lower midpoint
3) Enter the chain header node. The odd length returns the previous midpoint, and the even length returns the previous midpoint
4) Enter the chain header node. The odd length returns the one before the midpoint, and the even length returns the one before the next midpoint

Tips:

Find the upper midpoint. Only two nodes after the current node continue to jump

Find the lower midpoint. If there is a node after the current node, continue to jump

/**
 * Problem Description: speed pointer
 * <p>
 * 1)Enter the chain header node. The odd length returns the midpoint, and the even length returns the upper midpoint
 * 2)Enter the chain header node. The odd length returns the midpoint, and the even length returns the lower midpoint
 * 3)Enter the chain header node. The odd length returns the previous midpoint, and the even length returns the previous midpoint
 * 4)Enter the chain header node. The odd length returns the one before the midpoint, and the even length returns the one before the next midpoint
 */
public class LinkedListMid {

    public static class Node {
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }


    //1. Midpoint or upper midpoint
    public static Node midOrUpMidNode(Node head) {
        if (head == null || head.next == null || head.next.next == null) {
            return head;
        }
        Node slow = head.next;//Slow pointer
        Node fast = head.next.next;//Quick pointer
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

    //2. Midpoint or lower midpoint
    public static Node midOrDownMidNode(Node head) {
        if (head == null || head.next == null) {
            return head;
        }
        Node slow = head.next;
        Node fast = head.next.next;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

    //3. Return to the one before the midpoint or the one before the upper midpoint (slow one cloth less)
    public static Node midOrUpMidPreNode(Node head) {
        if (head == null || head.next == null || head.next.next == null) {
            return null;
        }
        Node slow = head;
        Node fast = head.next.next;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        
        return slow;
    }

    //4. Return to the one before the midpoint or the one before the next midpoint
    public static Node midOrDownMidPreNode(Node head) {
        if (head == null || head.next == null) {
            return null;
        }
        Node slow = head;
        Node fast = head.next.next;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

}

Second question

Question Description: whether it is palindrome structure. Given the head node of a single linked list, please judge whether the linked list is palindrome structure.

For example: 12321 √ 12312 ×

Prompt: 1 - > 2 - > 3 < - 2 < - 1

null

package com.lzf2.class08;

import java.util.Stack;

//Whether it is palindrome structure. Given the head node of a single linked list, please judge whether the linked list is palindrome structure.
public class IsPalindromeList {

    public static class Node{
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    // need n extra space
    public static boolean isPalindrome1(Node head) {
        Stack<Node> stack = new Stack<Node>();
        Node cur = head;
        while (cur != null) {
            stack.push(cur);
            cur = cur.next;
        }
        while (head != null) {
            if (head.value != stack.pop().value) {
                return false;
            }
            head = head.next;
        }
        return true;
    }
    // need n/2 extra space
    public static boolean isPalindrome2(Node head) {
        if (head == null || head.next == null) {
            return true;
        }
        Node right = head.next;
        Node cur = head;
        while (cur.next != null && cur.next.next != null) {
            right = right.next;
            cur = cur.next.next;
        }
        Stack<Node> stack = new Stack<Node>();
        while (right != null) {
            stack.push(right);
            right = right.next;
        }
        while (!stack.isEmpty()) {
            if (head.value != stack.pop().value) {
                return false;
            }
            head = head.next;
        }
        return true;
    }
    // need O(1) extra space
    public static boolean isPalindrome3(Node head) {
        if (head == null || head.next == null){
            return true;
        }
        //1. The speed pointer finds the middle position of the linked list
        Node slow = head;//midpoint
        Node fast = head;
        while (fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        //2. Adjust the linked list structure
        Node curr = slow.next;
        slow.next = null;
        while (curr != null){
            Node next = curr.next;
            curr.next = slow;
            slow = curr;
            curr = next;
        }
        //curr = null,slow in the last
        //3. For comparison, pay attention to slow. You need to readjust the linked list later
        Node R = slow;
        Node L = head;
        boolean res = true;
        while (L != null && R != null){
            if(L.value != R.value){
                res = false;
                break;//Don't end first. You need to adjust the linked list back
            }
            L = L.next;
            R = R.next;
        }
        //Tail slow
        curr = slow;
        Node pre = null;
        while (curr != null){
            Node next = curr.next;
            curr.next = pre;
            pre = curr;
            curr = next;
        }
        return res;
    }



    public static void printLinkedList(Node node) {
        System.out.print("Linked List: ");
        while (node != null) {
            System.out.print(node.value + " ");
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {

        Node head = null;
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(2);
        head.next.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(2);
        head.next.next.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindrome1(head) + " | ");
        System.out.print(isPalindrome2(head) + " | ");
        System.out.println(isPalindrome3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

    }
}

Question 3

Problem Description: divide the one-way linked list into the form of small on the left, equal in the middle and large on the right according to a certain value

Tip: the values are divided into smaller than the table, equal to the table, and larger than the table. Record the header and footer respectively.
Finally, connect the three linked lists

//The one-way linked list is divided into the form of small on the left, equal in the middle and large on the right according to a certain value
public class SmallerEqualBigger {
    //Node node
    public static class Node {
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    public static Node listPartition(Node head, int pivot) {
        Node sH = null;//small head
        Node sT = null;//small tail
        Node eH = null;//equal head
        Node eT = null;//equal tail
        Node mH = null;//big head
        Node mT = null;//big tail
        Node cur = head;
        while (cur != null) {
            Node next = cur.next;
            cur.next = null;
            if (cur.value > pivot) {
                if(mH == null){
                    mH = cur;
                    mT = cur;
                }else {
                    mT.next = cur;
                    mT = cur;
                }
            } else if (cur.value < pivot) {
                if (sH == null){
                    sH = cur;
                    sT = cur;
                }else {
                    sT.next = cur;
                    sT = cur;
                }
            } else {
                if (eH == null){
                    eH = cur;
                    eT = cur;
                }else {
                    eT.next = cur;
                    eT = cur;
                }
            }
            cur = next;
        }
        //Put the three areas together
        if (sT != null){
            sT.next = eH;
            eT = eH == null ? sT : eT;
        }
        if (eT != null){
            eT.next = mH;
        }
        return sH != null ? sH : (eH != null ?eH : mH);
    }
    
    public static void printLinkedList(Node node) {
        System.out.print("Linked List: ");
        while (node != null) {
            System.out.print(node.value + " ");
            node = node.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Node head1 = new Node(7);
        head1.next = new Node(9);
        head1.next.next = new Node(1);
        head1.next.next.next = new Node(8);
        head1.next.next.next.next = new Node(5);
        head1.next.next.next.next.next = new Node(2);
        head1.next.next.next.next.next.next = new Node(5);
        printLinkedList(head1);
        // head1 = listPartition1(head1, 4);
        head1 = listPartition(head1, 5);
        printLinkedList(head1);

    }
}

Question 4

Problem Description:

A special single linked list node class is described below
class Node {
int value;
Node next;
Node rand;
Node(int val) { value = val; }
}
rand pointer is a new pointer in the single linked list node structure. rand may point to any node in the linked list or null.
Given the head Node of an acyclic single linked list composed of Node types, please implement a function to copy the linked list and return the head Node of the copied new linked list.
[requirements]
Time complexity O(N), additional space complexity O(1)

Tip: copy each node and put it behind the original node. Then connect the rand pointer, and finally remove the pointer of the original node.

import java.util.HashMap;
//Copy a special linked list (with random pointer)
public class CopyListWithRandom {

    public static class Node {
        int value;
        Node next;
        Node rand;

        public Node(int value) {
            this.value = value;
        }
    }
    public static Node copyListWithRand2(Node head) {
        if (head == null){
            return null;
        }
        //1.copy each new node is placed behind the old node
        Node cur = head;
        while (cur != null){
            Node next = cur.next;
            cur.next = new Node(cur.value);
            cur.next.next = next;
            cur = next;
        }
        //2. Traverse two nodes at a time, and connect the random pointer of the new node
        cur = head;
        while (cur != null){
            cur.next.rand = cur.rand != null ? cur.rand.next : null;
            cur = cur.next.next;
        }
        //3. Separate the new node from the old node
        Node res = head.next;
        cur = head;
        while (cur != null){
            Node next = cur.next.next;
            Node copy = cur.next;
            cur.next = next;
            copy.next = next != null ? next.next : null;
            cur = next;
        }
        return res;
    }






    public static Node copyListWithRand1(Node head) {
        // key old node
        // value new node
        HashMap<Node, Node> map = new HashMap<Node, Node>();
        Node cur = head;
        while (cur != null) {
            map.put(cur, new Node(cur.value));
            cur = cur.next;
        }
        cur = head;
        while (cur != null) {
            // cur old
            // map.get(cur)
            // New. Next - > cur.next clone node found
            map.get(cur).next = map.get(cur.next);
            map.get(cur).rand = map.get(cur.rand);
            cur = cur.next;
        }
        return map.get(head);
    }

    public static void printRandLinkedList(Node head) {
        Node cur = head;
        System.out.print("order: ");
        while (cur != null) {
            System.out.print(cur.value + " ");
            cur = cur.next;
        }
        System.out.println();
        cur = head;
        System.out.print("rand:  ");
        while (cur != null) {
            System.out.print(cur.rand == null ? "- " : cur.rand.value + " ");
            cur = cur.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Node head = null;
        Node res1 = null;
        Node res2 = null;
        printRandLinkedList(head);
        res1 = copyListWithRand1(head);
        printRandLinkedList(res1);
        res2 = copyListWithRand2(head);
        printRandLinkedList(res2);
        printRandLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(4);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(6);

        head.rand = head.next.next.next.next.next; // 1 -> 6
        head.next.rand = head.next.next.next.next.next; // 2 -> 6
        head.next.next.rand = head.next.next.next.next; // 3 -> 5
        head.next.next.next.rand = head.next.next; // 4 -> 3
        head.next.next.next.next.rand = null; // 5 -> null
        head.next.next.next.next.next.rand = head.next.next.next; // 6 -> 4

        System.out.println("Original linked list:");
        printRandLinkedList(head);
        System.out.println("=========================");
        res1 = copyListWithRand1(head);
        System.out.println("Copy linked list of method 1:");
        printRandLinkedList(res1);
        System.out.println("=========================");
        res2 = copyListWithRand2(head);
        System.out.println("Copy linked list of method 2:");
        printRandLinkedList(res2);
        System.out.println("=========================");
        System.out.println("Original linked list after method 2 copy:");
        printRandLinkedList(head);
        System.out.println("=========================");

    }

}

Question 5

Given two single linked lists that may or may not have rings, the head nodes head1 and head2. Please implement a function. If two linked lists intersect, please return the first node of the intersection. If it does not intersect, null is returned
[requirements]
If the sum of the lengths of the two linked lists is N, the time complexity should reach O(N) and the additional space complexity should reach O(1).

Tips:

Two linked lists: 1) both have no rings, 2) both have rings, 3) one has a ring and the other has no ring
First judge whether the linked list has a ring
Provide processing methods for cases 1 and 2 to find the intersection node, and there must be no intersection point in case 3

/**
 * Given two single linked lists that may or may not have rings, the head nodes head1 and head2. Please implement a function. If two linked lists intersect, please return the first node of the intersection. If it does not intersect, null is returned
 * [Requirements]
 * If the sum of the lengths of the two linked lists is N, the time complexity should reach O(N) and the additional space complexity should reach O(1).
 */
public class FindFirstIntersectNode {
    public static class Node{
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    //Returns the intersection node of two linked lists, and returns null if there is no intersection
    public static Node getIntersectNode(Node head1,Node head2){
        if (head1 == null || head2 == null){
            return null;
        }
        Node loop1 = getLoopNode(head1);
        Node loop2 = getLoopNode(head2);
        if(loop1 == null && loop2 == null){
            return noLoop(head1,head2);
        }
        if(loop1 != null && loop2 != null){
            return bothLoop(head1,loop1,head2,loop2);
        }
        return null;
    }

    //Find the first ring entry node of the two linked lists. If there is no ring, null will be returned.
    public static Node getLoopNode(Node head){
        if(head == null || head.next == null || head.next.next == null){
            return null;
        }
        //Speed pointer
        Node fast = head.next.next;
        Node slow = head.next;
        while (fast != slow){
            if(fast.next == null || fast.next.next == null){
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
        }
        //fast and slow met
        fast = head;
        while (fast != slow){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

    //Handle the case where both are acyclic
    public static Node noLoop(Node head1,Node head2){
        if (head1 == null || head2 == null){
            return null;
        }
        Node cur1 = head1;
        Node cur2 = head2;
        int n = 0;
        while (cur1.next != null){
            n++;
            cur1 = cur1.next;
        }
        while (cur2.next != null){
            n--;
            cur2 = cur2.next;
        }
        //The tail nodes of the two linked lists are different and do not intersect
        if(cur1 != cur2){
            return null;
        }
        //Find out the long node and take the difference step (step n)
        cur1 = n > 0 ? head1 : head2;//Long
        cur2 = cur1 == head1 ? head2 : head1;//Short
        n = Math.abs(n);
        while (n != 0){
            cur1 = cur1.next;
            n--;
        }
        //Two linked lists go together
        while (cur1 != cur2){
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        return cur1;
    }
    //Handle the case where both have rings
    public static Node bothLoop(Node head1,Node loop1,Node head2,Node loop2){
        Node cur1 = null;
        Node cur2 = null;
        if (loop1 == loop2){//Same entry point
            cur1 = head1;
            cur2 = head2;
            int n = 0;
            while (cur1 != loop1){
                n++;
                cur1 = cur1.next;
            }
            while (cur2 != loop2){
                n--;
                cur2 = cur2.next;
            }
            cur1 = n > 0 ? head1 : head2;//long
            cur2 = cur1 == head1 ? head2 : head1;
            n = Math.abs(n);
            //Take the difference step
            while (n != 0){
                cur1 = cur1.next;
                n--;
            }
            //Two go together
            while (cur1 != cur2){
                cur1 = cur1.next;
                cur2 = cur2.next;
            }
            return cur1;
        }else {
            Node cur = loop1.next;
            while (cur != loop1){//Walk around
                if(cur == loop2){
                    return loop1;
                }
                cur = cur.next;
            }
            return null;//Two rings do not intersect
        }
    }

    public static void main(String[] args) {
        // 1->2->3->4->5->6->7->null
        Node head1 = new Node(1);
        head1.next = new Node(2);
        head1.next.next = new Node(3);
        head1.next.next.next = new Node(4);
        head1.next.next.next.next = new Node(5);
        head1.next.next.next.next.next = new Node(6);
        head1.next.next.next.next.next.next = new Node(7);

        // 0->9->8->6->7->null
        Node head2 = new Node(0);
        head2.next = new Node(9);
        head2.next.next = new Node(8);
        head2.next.next.next = head1.next.next.next.next.next; // 8->6
        System.out.println(getIntersectNode(head1, head2).value);

        // 1->2->3->4->5->6->7->4...
        head1 = new Node(1);
        head1.next = new Node(2);
        head1.next.next = new Node(3);
        head1.next.next.next = new Node(4);
        head1.next.next.next.next = new Node(5);
        head1.next.next.next.next.next = new Node(6);
        head1.next.next.next.next.next.next = new Node(7);
        head1.next.next.next.next.next.next = head1.next.next.next; // 7->4

        // 0->9->8->2...
        head2 = new Node(0);
        head2.next = new Node(9);
        head2.next.next = new Node(8);
        head2.next.next.next = head1.next; // 8->2
        System.out.println(getIntersectNode(head1, head2).value);

        // 0->9->8->6->4->5->6..
        head2 = new Node(0);
        head2.next = new Node(9);
        head2.next.next = new Node(8);
        head2.next.next.next = head1.next.next.next.next.next; // 8->6
        System.out.println(getIntersectNode(head1, head2).value);

    }
}

Question 6

Problem Description: delete a node without a header node

It can be implemented, but it is not really deleting nodes, but only changing values, which will cause problems in some scenarios.
And the last node cannot be deleted.

public static void delete(Node node){
    if(node == null){
        return;
    }
    Node next = node.next;
    if(next == null){//The current node is the last node and cannot be deleted
        return;
    }
    node.value = next.value;
    node.next = next.next;
}

Tags: Algorithm data structure Interview linked list

Posted on Thu, 14 Oct 2021 18:02:32 -0400 by acheoacheo