基本概念参考程序员面试指南 这种方法关键是理解思想,实际的代码非常简单。
leetcode变形题
398. Random Pick Index
Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array.
Note:
The array size can be very large. Solution that uses too much extra space will not pass the judge.
Example:
int[] nums = new int[] {1,2,3,3,3}; Solution solution = new Solution(nums); // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. solution.pick(3); // pick(1) should return 0. Since in the array only nums[0] is equal to 1. solution.pick(1);
要求在一串非常大的数中找一个给定数,如果有重复值,选定一个重复值,但是要求这些重复值被选定的概率相等。
思路:这还是一个蓄水池等概率选数问题。不同的是,多了和tartget不相等的数,这些数和目标没有任何关联。
这个问题怎么转变成蓄水池问题?
对于给定的数target,在这串数中只考虑和tartget相等的计数,n。蓄水池的容量为1.
过程是,如果当前的数是target,已经出现的target数目为n,那么以1/n的概率将当前的选定数替换成新的target。就能保证,遍历到当前位置,所有出现的target被选中的概率都是1/n。
class Solution {
vector<int> nums;
int pos=-1;
public:
Solution(vector<int> nums) {
this->nums=nums;
}
int pick(int target) {
int n=0;//统计target出现的次数
for(int i=0;i<nums.size();i++)
{
if(nums[i]!=target) continue;
if(n==0)
{
n++;
pos=i;
}
else
{
n++;
if(rand()%n==0) pos=i;
}
}
return pos;
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* int param_1 = obj.pick(target);
*/
382. 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.
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?
Example:
// Init a singly linked list [1,2,3]. ListNode head = new ListNode(1); head.next = new ListNode(2); head.next.next = new ListNode(3); Solution solution = new Solution(head); // getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning. solution.getRandom();
Seen this question in a real interview before?
这是一个典型的蓄水池问题,蓄水池容量是1.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
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) {
MyHead=head;
ListNode* cur=MyHead;
while(head->next)
{
cur->next=head->next;
cur=cur->next;
head=head->next;
}
}
/** Returns a random node's value. */
int getRandom() {
ListNode* cur=MyHead;
int res=0;
n=0;
while(cur)
{
n++;
if(n==1)
{
res=cur->val;
}
else
{
if(rand()%n==0) res=cur->val;
}
cur=cur->next;
}
return res;
}
private:
ListNode* MyHead=nullptr;
int n;
};
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(head);
* int param_1 = obj.getRandom();
*/