382-linked-list-random-node¶
Try it on leetcode
Description¶
Given a singly linked list, return a random node's value from the linked list. Each node must have the same probability of being chosen.
Implement the Solution
class:
Solution(ListNode head)
Initializes the object with the integer array nums.int getRandom()
Chooses a node randomly from the list and returns its value. All the nodes of the list should be equally likely to be choosen.
Example 1:

Input ["Solution", "getRandom", "getRandom", "getRandom", "getRandom", "getRandom"] [[[1, 2, 3]], [], [], [], [], []] Output [null, 1, 3, 2, 2, 3]Explanation Solution solution = new Solution([1, 2, 3]); solution.getRandom(); // return 1 solution.getRandom(); // return 3 solution.getRandom(); // return 2 solution.getRandom(); // return 2 solution.getRandom(); // return 3 // getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
Constraints:
- The number of nodes in the linked list will be in the range
[1, 104]
. -104 <= Node.val <= 104
- At most
104
calls will be made togetRandom
.
Follow up:
- What if the linked list is extremely large and its length is unknown to you?
- Could you solve this efficiently without using extra space?
Solution(Python)¶
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
# @Problem Statement:
# Given a Singly LinkedList return a RandomNode
#
# @Input: Head Node
# @Output: Random Node
#
# @sample Input:
# 1.[1,2,3] get Random -> 3 ,2,1,1,2,3
# All of them with equal probabaility
#
# @constraints:
# * N = [1,10^4]
# * -10^4 <= N.val <= 10^4
# * Atmost 10^4 calls
#
# @Solutions:
# 1. Using array of node values:
# Idea:
# * init() -> stores linkedList in a array
# * getrandom -> return random sample from array
#
# Complexity Analysis:
# * Time Complexity:init() -> O(n)
# getrandom() -> O(1)
# * Space Complexity: O(n)
# code:
# def __init__(self, head: Optional[ListNode]):
# self.arr = []
#
# while head:
# self.arr.append(head.val)
# head = head.next
# self.n = len(self.arr)
#
# def getRandom(self) -> int:
# randIn = int(random.random()*self.n)
#
# return self.arr[randIn]
# --------------------------------------------------
# 2.By Maintaing Reservior Array:
# At Start We store the Reservior array of size k
# with elements from the input
# To ensure equal probability of picking elements from the array
# i.e k/n for all elements we should pick random values within
# k for values outside k we can discard it
#
# Complexity Analysis:
# * Time Complexity:init() -> O(1)
# getrandom() -> O(n)
# * Space Complexity: O(1)
def __init__(self, head: Optional[ListNode]):
self.headNode = head
def getRandom(self) -> int:
k = 1
chosen_val = 0
cur = self.headNode
while cur:
if random.random() < 1 / k:
chosen_val = cur.val
cur = cur.next
k += 1
return chosen_val
# Your Solution object will be instantiated and called as such:
# obj = Solution(head)
# param_1 = obj.getRandom()