# Java Program For Selecting A Random Node From A Singly Linked List

Given a singly linked list, select a random node from the linked list (the probability of picking a node should be 1/N if there are N nodes in the list). You are given a random number generator.

Below is a Simple Solution:

- Count the number of nodes by traversing the list.
- Traverse the list again and select every node with probability 1/N. The selection can be done by generating a random number from 0 to N-i for i’th node, and selecting the i’th node only if the generated number is equal to 0 (or any other fixed number from 0 to N-i).

We get uniform probabilities with the above schemes.

i = 1, probability of selecting first node = 1/N i = 2, probability of selecting second node = [probability that first node is not selected] * [probability that second node is selected] = ((N-1)/N)* 1/(N-1) = 1/N

Similarly, probabilities of other selecting other nodes is 1/N

The above solution requires two traversals of linked list.

**How to select a random node with only one traversal allowed?**

The idea is to use Reservoir Sampling. Following are the steps. This is a simpler version of Reservoir Sampling as we need to select only one key instead of k keys.

(1) Initialize result as first node result = head->key (2) Initialize n = 2 (3) Now one by one consider all nodes from 2nd node onward. (a) Generate a random number from 0 to n-1. Let the generated random number is j. (b) If j is equal to 0 (we could choose other fixed numbers between 0 to n-1), then replace result with the current node. (c) n = n+1 (d) current = current->next

Below is the implementation of above algorithm.

## Java

`// Java program to select a random ` `// node from singly linked list ` `import` `java.util.*; ` ` ` `// Linked List Class ` `class` `LinkedList ` `{ ` ` ` `// head of list ` ` ` `static` `Node head; ` ` ` ` ` `// Node Class ` ` ` `static` `class` `Node ` ` ` `{ ` ` ` `int` `data; ` ` ` `Node next; ` ` ` ` ` `// Constructor to create ` ` ` `// a new node ` ` ` `Node(` `int` `d) ` ` ` `{ ` ` ` `data = d; ` ` ` `next = ` `null` `; ` ` ` `} ` ` ` `} ` ` ` ` ` `// A reservoir sampling-based function ` ` ` `// to print a random node from a ` ` ` `// linked list ` ` ` `void` `printrandom(Node node) ` ` ` `{ ` ` ` `// If list is empty ` ` ` `if` `(node == ` `null` `) ` ` ` `{ ` ` ` `return` `; ` ` ` `} ` ` ` ` ` `// Use a different seed value so ` ` ` `// that we don't get same result ` ` ` `// each time we run this program ` ` ` `Math.abs(UUID.randomUUID().getMostSignificantBits()); ` ` ` ` ` `// Initialize result as first node ` ` ` `int` `result = node.data; ` ` ` ` ` `// Iterate from the (k+1)th element ` ` ` `// to nth element ` ` ` `Node current = node; ` ` ` `int` `n; ` ` ` `for` `(n = ` `2` `; current != ` `null` `; n++) ` ` ` `{ ` ` ` `// change result with ` ` ` `// probability 1/n ` ` ` `if` `(Math.random() % n == ` `0` `) ` ` ` `{ ` ` ` `result = current.data; ` ` ` `} ` ` ` ` ` `// Move to next node ` ` ` `current = current.next; ` ` ` `} ` ` ` `System.out.println( ` ` ` `"Randomly selected key is "` `+ result); ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `public` `static` `void` `main(String[] args) ` ` ` `{ ` ` ` `LinkedList list = ` `new` `LinkedList(); ` ` ` `list.head = ` `new` `Node(` `5` `); ` ` ` `list.head.next = ` `new` `Node(` `20` `); ` ` ` `list.head.next.next = ` `new` `Node(` `4` `); ` ` ` `list.head.next.next.next = ` `new` `Node(` `3` `); ` ` ` `list.head.next.next.next.next = ` `new` `Node(` `30` `); ` ` ` `list.printrandom(head); ` ` ` `} ` `} ` `// This code is contributed by Mayank Jaiswal ` |

Note that the above program is based on the outcome of a random function and may produce different output.

**How does this work?**

Let there be total N nodes in list. It is easier to understand from the last node.

The probability that the last node is result simply 1/N [For last or N’th node, we generate a random number between 0 to N-1 and make the last node as a result if the generated number is 0 (or any other fixed number]

The probability that second last node is result should also be 1/N.

The probability that the second last node is result = [Probability that the second last node replaces result] X [Probability that the last node doesn't replace the result] = [1 / (N-1)] * [(N-1)/N] = 1/N

Similarly, we can show probability for 3^{rd} last node and other nodes.

Please refer complete article on Select a Random Node from a Singly Linked List for more details!