Python Program For Selecting A Random Node From A Singly Linked List
Last Updated :
21 Jul, 2022
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.
Python
# Python program to randomly select a
# node from singly linked list
import random
# Node class
class Node:
# Constructor to initialize the
# node object
def __init__(self, data):
self.data= data
self.next = None
class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
# A reservoir sampling-based function
# to print a random node from a
# linked list
def printRandom(self):
# If list is empty
if self.head is None:
return
if self.head and not self.head.next:
print "Randomly selected key is %d" %(self.head.data)
# Use a different seed value so that we don't get
# same result each time we run this program
random.seed()
# Initialize result as first node
result = self.head.data
# Iterate from the (k+1)th element nth element
# because we iterate from (k+1)th element, or
# the first node will be picked more easily
current = self.head.next
n = 2
while(current is not None):
# Change result with probability 1/n
if (random.randrange(n) == 0 ):
result = current.data
# Move to next node
current = current.next
n += 1
print "Randomly selected key is %d" %(result)
# Function to insert a new node at
# the beginning
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
# Utility function to print the linked
# LinkedList
def printList(self):
temp = self.head
while(temp):
print temp.data,
temp = temp.next
# Driver code
llist = LinkedList()
llist.push(5)
llist.push(20)
llist.push(4)
llist.push(3)
llist.push(30)
llist.printRandom()
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)
Time Complexity: O(n), as we are using a loop to traverse n times. Where n is the number of nodes in the linked list.
Auxiliary Space: O(1), as we are not using any extra space.
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 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 3rd last node and other nodes. Please refer complete article on Select a Random Node from a Singly Linked List for more details!
Similar Reads
Python program to select Random value from list of lists Given a list of lists. The task is to extract a random element from it. Examples: Input : test_list = [[4, 5, 5], [2, 7, 4], [8, 6, 3]] Output : 7 Explanation : Random number extracted from Matrix.Input : test_list = [[4, 5, 5], [2, 7, 4], [8, 6, 3]], r_no = 2 Output : 6 Explanation : Random number
4 min read
Python Program For Cloning A Linked List With Next And Random Pointer- Set 2 We have already discussed 2 different ways to clone a linked list. In this post, one more simple method to clone a linked list is discussed. Recommended: Please solve it on "PRACTICE" first, before moving on to the solution. The idea is to use Hashing. Below is algorithm. Traverse the original link
3 min read
Python Program For Swapping Nodes In A Linked List Without Swapping Data Given a linked list and two keys in it, swap nodes for two given keys. Nodes should be swapped by changing links. Swapping data of nodes may be expensive in many situations when data contains many fields. It may be assumed that all keys in the linked list are distinct. Examples: Input : 10->15-
5 min read
Python Program For Cloning A Linked List With Next And Random Pointer In O(1) Space Given a linked list having two pointers in each node. The first one points to the next node of the list, however, the other pointer is random and can point to any node of the list. Write a program that clones the given list in O(1) space, i.e., without any extra space. Examples: Input : Head of the
4 min read
Python Program for Deleting a Node in a Linked List We have discussed Linked List Introduction and Linked List Insertion in previous posts on a singly linked list.Let us formulate the problem statement to understand the deletion process. Given a 'key', delete the first occurrence of this key in the linked list. Iterative Method:To delete a node from
3 min read
Python program to find middle of a linked list using one traversal Given a singly linked list, find the middle of the linked list. Given a singly linked list, find the middle of the linked list. For example, if the given linked list is 1->2->3->4->5 then the output should be 3. Method 1: Traverse the whole linked list and count the no. of nodes. Now tra
5 min read
Python Program To Delete Alternate Nodes Of A Linked List Given a Singly Linked List, starting from the second node delete all alternate nodes of it. For example, if the given linked list is 1->2->3->4->5 then your function should convert it to 1->3->5, and if the given linked list is 1->2->3->4 then convert it to 1->3. Recomm
3 min read
Python program to randomly create N Lists of K size Given a List, the task is to write a Python program to randomly generate N lists of size K. Examples: Input : test_list = [6, 9, 1, 8, 4, 7], K, N = 3, 4 Output : [[8, 7, 6], [8, 6, 9], [8, 1, 6], [7, 8, 9]] Explanation : 4 rows of 3 length are randomly extracted. Input : test_list = [6, 9, 1, 8, 4,
5 min read
Python Program For Pairwise Swapping Elements Of A Given Linked List Given a singly linked list, write a function to swap elements pairwise. Input: 1->2->3->4->5->6->NULL Output: 2->1->4->3->6->5->NULL Input: 1->2->3->4->5->NULL Output: 2->1->4->3->5->NULL Input: 1->NULL Output: 1->NULL For examp
2 min read
Python Program For Pointing Arbit Pointer To Greatest Value Right Side Node In A Linked List Given singly linked list with every node having an additional âarbitraryâ pointer that currently points to NULL. We need to make the âarbitraryâ pointer to the greatest value node in a linked list on its right side. A Simple Solution is to traverse all nodes one by one. For every node, find the node
7 min read