Easily get the chain surface test questions

Preface

Boundary conditions to check whether the linked list code is correct:

  1. If the linked list is null, does the code run normally?
  2. If the linked list has only one node, does the code run normally?
  3. If the linked list has only two nodes, does the code run normally?
  4. When the code logic processes the head node and the end node, does the code run normally?

The structure and printing of the linked list

  public static void main(String[] args) {
    
    
        int[] arr = {
    
    1, 3, 5, 7, 9, 11, 13, 15, 17};
        LinkedListDemo linkedListDemo = new LinkedListDemo();
        Node head1 = linkedListDemo.buildLinkedList(arr);
        linkedListDemo.display(head1);
        // 链表逆序
        linkedListDemo.display(linkedListDemo.reverseList(head1));
        linkedListDemo.display(head1);
    }

    private static class Node {
    
    
        final Integer item;
        Node next;

        Node(Integer item, Node next) {
    
    
            this.item = item;
            this.next = next;
        }
    }
    
    /**
     * 打印链表
     *
     * @param header
     */
    public void display(Node header) {
    
    
        Node p = header;
        while (p != null) {
    
    
            System.out.print(p.item + " ");
            p = p.next;
        }
        System.out.println();
    }

    /**
     * 通过数组构造一个链表
     *
     * @param arr
     * @return
     */
    public Node buildLinkedList(int[] arr) {
    
    
        if (Objects.isNull(arr) || arr.length < 1) {
    
    
            throw new IllegalArgumentException("illegal arr");
        }
        Node head = new Node(arr[0], null);
        if (arr.length >= 2) {
    
    
            Node p = head;
            for (int i = 1; i < arr.length; i++) {
    
    
                Node temp = new Node(arr[i], null);
                p.next = temp;
                p = temp;
            }
        }
        return head;
    }

    public void checkNull(Node head) {
    
    
        if (head == null) {
    
    
            throw new NullPointerException();
        }
    }

Reverse order of singly linked list

 /**
     * 单链表逆序
     *
     * @param head
     */
    public Node reverseList(Node head) {
    
    
        this.checkNull(head);
        Node p = head.next;
        head.next = null;
        Node temp;
        while (p != null) {
    
    
            temp = p.next;
            p.next = head;
            head = p;
            p = temp;
        }
        return head;
    }

Merge two ordered linked lists

 /**
     * 合并两个有序链表
     *
     * @param head1
     * @param head2
     * @return
     */
    public Node mergeTwoSortedLinkedList(Node head1, Node head2) {
    
    
        if (head1 == null && head2 == null) {
    
    
            throw new IllegalArgumentException("Illegal params");
        }
        if (head1 == null) {
    
    
            return head2;
        }

        if (head2 == null) {
    
    
            return head1;
        }
        // 设置一个哨兵结点
        Node head = new Node(null, null);
        Node p = head;
        while (head1 != null && head2 != null) {
    
    
            if (head1.item < head2.item) {
    
    
                p.next = head1;
                p = head1;
                head1 = head1.next;
            } else {
    
    
                p.next = head2;
                p = head2;
                head2 = head2.next;
            }
        }

        // 拼接链表的剩下部分
        if (head1 != null) {
    
    
            p.next = head1;
        }

        if (head2 != null) {
    
    
            p.next = head2;
        }

        p = null;
        return head.next;
    }

Delete the nth node from the bottom of the linked list

Declare two pointers fast and slow, let the fast pointer go n steps, and then move the two pointers backward at the same time, until the fast pointer reaches the last node, the next node of the slow pointer is the node to be deleted.

  /**
     * 删除链表倒数第 n 个结点
     *
     * @param head
     * @param n
     * @return
     */
    public Node removeNode(Node head, Integer n) {
    
    
        if (head == null) {
    
    
            return null;
        }
        Node slow = head, fast = head;
        // 让快指针先走 n 步
        int i = 0;
        while (fast != null && i < n) {
    
    
            fast = fast.next;
            i++;
        }
        // 如果指定的 n 大于链表的长度,不进行删除处理
        if (n > i) {
    
    
            return head;
        }

        //如果指定的 n 等于链表的长度,删除第一个结点
        if (fast == null) {
    
    
            return head.next;
        }
        // 同时移动两个指针直到快指针指向尾结点
        while (fast.next != null) {
    
    
            slow = slow.next;
            fast = fast.next;
        }
        // 删除 slow.next
        slow.next = slow.next.next;
        return head;
    }

Find the middle node of the linked list

Declare fast and slow pointers, slow pointers only traverse one node, fast pointer speed is 2 times, when the fast pointer points to the last node of the linked list (the number of summary points in the linked list is odd) or the fast pointer points to the penultimate node (the number of summary points in the linked list is Even), the slow pointer points to the middle node of the linked list.

    /**
     * 找出链表的中间结点
     *
     * @param head
     * @return
     */
    public Node getMiddleNode(Node head) {
    
    
        this.checkNull(head);
        Node fast = head, slow = head;
        while (fast != null && fast.next != null && fast.next.next != null) {
    
    
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

Detection of rings in linked lists

Reference: Detection of rings in the linked list

Guess you like

Origin blog.csdn.net/jiaobuchong/article/details/84675815