Find the nth element from the end of linked list in one loop

·

2 min read

This is one interview question from the big five. The interviewer asked me to resolve the nth element from the end of a linked list on a whiteboard. I tried to resolve it at first in the easiest way.

ary_start.png

Go through this linked list and find out the size is 9, nth is 3 so 9 - 3 is 6 so at the 6 th with begin index 0 is the target node, so the node with value 5.

Then the interviewer asked me it takes 2 iteration, do you think there is a way to resolve it in one loop. i was stumped. The interviewer gave me one suggestion like sublist, be frankly, i don't think that solution is accurate afterward.

I worked out somehow like this based on his suggestion. One node with 2 pointers head and tail (pink one), the head pointed to the begin of the linked list and the tail pointed to the nth node, then moving the node towards the end, which means when the tail arrived the end, the head would point on the target node.

moving_final.png

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

    private Node tail;
    private Node head;

    private static Node nodeList(int [] numbers) {
        Node node = new Node();
        Node currentNode = null;
        for (int i = 0; i < numbers.length; i++) {
            if (i == 0) {
                node.value = numbers[i];
                node.next = null;
                currentNode = node;
            } else {
                insertAfter (currentNode, numbers[i]);
                currentNode = currentNode.next;
            }
        }
        return node;
    }

    private static Node nodePointer(Node nodelist, int backwardNth) {
        Node pointer = new Node();
        pointer.head = nodelist;
        pointer.tail = nodelist;
        Node currentNode = nodelist;
        for (int i = 0; i <= backwardNth; i++) {
            pointer.tail = currentNode;
            currentNode = currentNode.next;
        }
        return pointer;
    }

    public static Node retrieveBackWard(Node pointer) {
        Node currentNode = pointer.tail;
        Node targetNode = pointer.head;
        while(currentNode != null) {
            if (currentNode == null) {
                return targetNode;
            }
            currentNode = currentNode.next;
            targetNode = targetNode.next;
        }
        return targetNode;
    }

    private static void insertAfter(Node pre, int value) {
        Node node = new Node();
        node.value = value;
        pre.next = node;
    }

    public static void main(String [] args) {
        int nth = 3;
        int[] ary = new int[] {6,4,2,7,1,3,5,9,8};
        Node nodelist = nodeList(ary);
        Node pointer = nodePointer(nodelist, nth);
        Node backwardsNth = retrieveBackWard(pointer);
        System.out.println(String.format("backwards %s th is %s", nth,  backwardsNth.value));
    }
}

You can also get the code from my git repository

raw.githubusercontent.com/bigtomate/example..