2023-03-10 Daily Challenge

Today I have done leetcode's March LeetCoding Challenge with cpp.

March LeetCoding Challenge 10

Description

Linked List Random Node

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.

 

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 to getRandom.

 

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

auto speedup = [](){
  cin.tie(nullptr);
  cout.tie(nullptr);
  ios::sync_with_stdio(false);
  return 0;
}();
class Solution {
  ListNode* head;
  mt19937 generator;
  uniform_real_distribution<double> distribution = uniform_real_distribution<double>(0.0, 1.0);
  function<double(void)> rng = bind(distribution, generator);
public:
  /** @param head The linked list's head.
      Note that the head is guaranteed to be not null, so it contains at least one node. */
  Solution(ListNode* head) {
    this->head = head;
  }
  
  /** Returns a random node's value. */
  int getRandom() {
    ListNode *cur = head;
    double curIndex = 1;
    int result = -1;
    while(cur) {
      if(rng() < 1 / curIndex) result = cur->val;
      cur = cur->next;
      curIndex += 1;
    }
    return result;
  }
};

// Accepted
// 8/8 cases passed (36 ms)
// Your runtime beats 7.46 % of cpp submissions
// Your memory usage beats 8.14 % of cpp submissions (16.9 MB)