HomeLeetcode382. Linked List Random Node - Leetcode Solutions

382. Linked List Random Node – Leetcode Solutions

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 head of the singly-linked list head.
  • 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 chosen.

Examples:

Example 1:

Input
["Solution", "getRandom", "getRandom", "getRandom", "getRandom", "getRandom"]
[[[1, 2, 3]], [], [], [], [], []]
Output
[null, 1, 3, 2, 2, 3]

Solution in Python

Solution Design

  1. Initialization:
    • Store the head of the linked list.
    • This allows us to access and iterate over the list from the beginning each time we call getRandom.
  2. getRandom Method:
    • We perform a single traversal of the list using a reservoir sampling approach to pick a random node with equal probability.
    • As we traverse each node, we decide whether to select it as our random node based on a progressively smaller probability:
      • For the i-th node, we select it with a probability of 1\i​.
    • This approach guarantees that each node has an equal chance of being selected, regardless of the list’s length.
Python
class Solution:
    
    def __init__(self, head: Optional[ListNode]):
        # Initialize the Solution with the head of the linked list
        self.head = head

    def getRandom(self) -> int:
        # Initialize variables for reservoir sampling
        reservoir = -1  # Placeholder for the value of the selected node
        current = self.head  # Start at the head of the list
        n = 0  # Tracks the index of the current node for probability calculation
        
        # Traverse the linked list
        while current:
            n += 1  # Increment the count of nodes seen so far
            # Decide to replace the reservoir with current node's value with probability 1/n
            if random.randint(1, n) == 1:
                reservoir = current.val
            # Move to the next node
            current = current.next
        
        return reservoir  # Return the value of the selected node

Explanation of getRandom:

  • Initialization:
    • reservoir: Holds the value of the randomly chosen node, initially set to -1 (or any placeholder value).
    • current: A pointer to traverse the list starting from head.
    • n: Tracks the position of the current node for determining selection probability.
  • Reservoir Sampling Logic:
    • For each node visited:
      • Increment n to reflect the total nodes encountered.
      • Use random.randint(1, n) to simulate a probability of 1/n​. If the result is 1, replace reservoir with the current node’s value.
    • Continue until reaching the end of the list, at which point reservoir holds the value of the randomly chosen node.

Solution in C++

C++
class Solution {
private:
    ListNode* head; // Head of the linked list

public:
    // Constructor to initialize the Solution with the head of the linked list.
    Solution(ListNode* head) {
        this->head = head;
    }
    
    // Function to get a random node's value using Reservoir Sampling.
    int getRandom() {
        int result;             // To store the value of the selected node
        int count = 1;          // Counter to track the number of nodes traversed
        
        ListNode* current = head; // Start from the head of the list

        // Traverse the linked list
        while (current != nullptr) {
            // Reservoir sampling probability logic:
            // Replace result with current node's value with probability 1/count.
            if (rand() % count == 0) {
                result = current->val; // Select the current node's value
            }
            
            count++;             // Increment the node counter
            current = current->next; // Move to the next node
        }

        return result; // Return the randomly selected node's value
    }
};

Solution in Javascript

JavaScript
var Solution = function(head) {
    // Initialize the Solution class with the head of the linked list.
    this.head = head;
};

/**
 * Chooses a random node from the linked list and returns its value.
 * Each node must have the same probability of being chosen.
 * @return {number} - The value of the randomly chosen node
 */
Solution.prototype.getRandom = function() {
    let result = null; // Variable to store the result (value of the randomly chosen node)
    let current = this.head; // Start from the head of the linked list
    let index = 0; // Tracks the index of the current node as we traverse the list

    // Traverse the entire linked list
    while (current !== null) {
        // For each node, decide if it should be chosen based on its probability
        // Probability of choosing the current node decreases as the index increases
        if (Math.floor(Math.random() * (index + 1)) === 0) {
            result = current.val; // Select the current node's value as the result
        }

        // Move to the next node in the list
        current = current.next;
        index++; // Increment the index for the next node
    }

    return result; // Return the value of the randomly chosen node
};

Solution in Java

Java
class Solution {
    // Instance variable to hold the head of the linked list
    private ListNode head;
    // Random object to generate random numbers
    private Random rand;

    /**
     * Constructor to initialize the object with the head of the singly-linked list.
     * @param head the head of the linked list.
     */
    public Solution(ListNode head) {
        this.head = head; // Save the head of the list
        this.rand = new Random(); // Initialize Random object
    }
    
    /**
     * Chooses a random node's value from the linked list.
     * @return the value of the randomly selected node.
     */
    public int getRandom() {
        int result = 0; // Variable to store the result
        ListNode current = head; // Start with the head node
        int count = 0; // Counter to keep track of the node index
        
        // Traverse through the linked list
        while (current != null) {
            count++; // Increment node count
            
            // Generate a random number in the range [0, count-1]
            // If it's 0, update the result with the current node's value
            if (rand.nextInt(count) == 0) {
                result = current.val;
            }
            
            // Move to the next node
            current = current.next;
        }
        
        return result; // Return the randomly selected node's value
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular