public Node clone(Node head) {
        Node cursor = head;
        // add a copy of node after every node with data copied
        while(cursor != null) {
            Node copyNode = new Node(cursor.data ,cursor.next, null);
            cursor.next = copyNode;
            cursor = copyNode.next;
        }

        // now populate the arbitary pointer
        cursor = head;
        while(cursor != null && cursor.next != null) {
            if(cursor.random != null) {
                cursor.next.random = cursor.random.next;
            }
            cursor = cursor.next.next;
        }

        Node copy = head.next;
        Node response = copy;
        cursor = head;
        // here we break the interleaving between two lists one by one
        while(cursor!= null && cursor.next != null && copy!= null) {
            cursor.next = copy.next;
            if(cursor.next!= null) {
                copy.next = cursor.next.next;
            }

            cursor = cursor.next;
            copy = copy.next;
        }

        return response;
    }